3 # generate python wrappers from the XML API description
9 enums
= {} # { enumType: { enumConstant: enumValue } }
10 lxc_enums
= {} # { enumType: { enumConstant: enumValue } }
11 qemu_enums
= {} # { enumType: { enumConstant: enumValue } }
13 params
= [] # [ (parameName, paramValue)... ]
22 #######################################################################
24 # That part if purely the API acquisition phase from the
25 # libvirt API description
27 #######################################################################
38 "libvirt-domain-checkpoint",
39 "libvirt-domain-snapshot",
52 # Attach parser to an unmarshalling object. return both objects.
54 parser
= xml
.sax
.make_parser()
55 parser
.setContentHandler(target
)
58 class docParser(xml
.sax
.handler
.ContentHandler
):
60 self
._methodname
= None
64 self
.startElement
= self
.start
65 self
.endElement
= self
.end
66 self
.characters
= self
.data
72 def getmethodname(self
):
73 return self
._methodname
77 print("data %s" % text
)
78 self
._data
.append(text
)
80 def cdata(self
, text
):
82 print("data %s" % text
)
83 self
._data
.append(text
)
85 def start(self
, tag
, attrs
):
87 print("start %s, %s" % (tag
, attrs
))
92 self
.function_cond
= None
93 self
.function_args
= []
94 self
.function_descr
= None
95 self
.function_return
= None
96 self
.function_file
= None
97 self
.function_module
= None
98 if 'name' in attrs
.keys():
99 self
.function
= attrs
['name']
100 if 'file' in attrs
.keys():
101 self
.function_file
= attrs
['file']
102 if 'module' in attrs
.keys():
103 self
.function_module
= attrs
['module']
109 if self
.in_function
== 1:
110 self
.function_arg_name
= None
111 self
.function_arg_type
= None
112 self
.function_arg_info
= None
113 if 'name' in attrs
.keys():
114 self
.function_arg_name
= attrs
['name']
115 if self
.function_arg_name
== 'from':
116 self
.function_arg_name
= 'frm'
117 if 'type' in attrs
.keys():
118 self
.function_arg_type
= attrs
['type']
119 if 'info' in attrs
.keys():
120 self
.function_arg_info
= attrs
['info']
121 elif tag
== 'return':
122 if self
.in_function
== 1:
123 self
.function_return_type
= None
124 self
.function_return_info
= None
125 self
.function_return_field
= None
126 if 'type' in attrs
.keys():
127 self
.function_return_type
= attrs
['type']
128 if 'info' in attrs
.keys():
129 self
.function_return_info
= attrs
['info']
130 if 'field' in attrs
.keys():
131 self
.function_return_field
= attrs
['field']
133 # enums come from header files, hence virterror.h
134 if attrs
['file'] in libvirt_headers
+ ["virerror", "virterror"]:
135 enum(attrs
['type'],attrs
['name'],attrs
['value'])
136 elif attrs
['file'] == "libvirt-lxc":
137 lxc_enum(attrs
['type'],attrs
['name'],attrs
['value'])
138 elif attrs
['file'] == "libvirt-qemu":
139 qemu_enum(attrs
['type'],attrs
['name'],attrs
['value'])
141 if "string" in attrs
.keys():
142 params
.append((attrs
['name'], attrs
['string']))
146 print("end %s" % tag
)
147 if tag
== 'function':
148 # fuctions come from source files, hence 'virerror.c'
149 if self
.function
is not None:
150 if self
.function_module
in libvirt_headers
+ \
151 ["event", "virevent", "virerror", "virterror"]:
152 function(self
.function
, self
.function_descr
,
153 self
.function_return
, self
.function_args
,
154 self
.function_file
, self
.function_module
,
156 elif self
.function_module
== "libvirt-lxc":
157 lxc_function(self
.function
, self
.function_descr
,
158 self
.function_return
, self
.function_args
,
159 self
.function_file
, self
.function_module
,
161 elif self
.function_module
== "libvirt-qemu":
162 qemu_function(self
.function
, self
.function_descr
,
163 self
.function_return
, self
.function_args
,
164 self
.function_file
, self
.function_module
,
166 elif self
.function_file
== "python":
167 function(self
.function
, self
.function_descr
,
168 self
.function_return
, self
.function_args
,
169 self
.function_file
, self
.function_module
,
171 elif self
.function_file
== "python-lxc":
172 lxc_function(self
.function
, self
.function_descr
,
173 self
.function_return
, self
.function_args
,
174 self
.function_file
, self
.function_module
,
176 elif self
.function_file
== "python-qemu":
177 qemu_function(self
.function
, self
.function_descr
,
178 self
.function_return
, self
.function_args
,
179 self
.function_file
, self
.function_module
,
183 if self
.in_function
== 1:
184 self
.function_args
.append([self
.function_arg_name
,
185 self
.function_arg_type
,
186 self
.function_arg_info
])
187 elif tag
== 'return':
188 if self
.in_function
== 1:
189 self
.function_return
= [self
.function_return_type
,
190 self
.function_return_info
,
191 self
.function_return_field
]
196 if self
.in_function
== 1:
197 self
.function_descr
= str
202 if self
.in_function
== 1:
203 self
.function_cond
= str
206 def function(name
, desc
, ret
, args
, file, module
, cond
):
208 if onlyOverrides
and name
not in functions
:
210 if name
== "virConnectListDomains":
211 name
= "virConnectListDomainsID"
212 functions
[name
] = (desc
, ret
, args
, file, module
, cond
)
214 def qemu_function(name
, desc
, ret
, args
, file, module
, cond
):
216 if onlyOverrides
and name
not in qemu_functions
:
218 qemu_functions
[name
] = (desc
, ret
, args
, file, module
, cond
)
220 def lxc_function(name
, desc
, ret
, args
, file, module
, cond
):
222 if onlyOverrides
and name
not in lxc_functions
:
224 lxc_functions
[name
] = (desc
, ret
, args
, file, module
, cond
)
226 def enum(type, name
, value
):
227 if type not in enums
:
229 if (name
.startswith('VIR_DOMAIN_EVENT_ID_') or
230 name
.startswith('VIR_NETWORK_EVENT_ID_')):
231 event_ids
.append(name
)
232 if value
== 'VIR_TYPED_PARAM_INT':
234 elif value
== 'VIR_TYPED_PARAM_UINT':
236 elif value
== 'VIR_TYPED_PARAM_LLONG':
238 elif value
== 'VIR_TYPED_PARAM_ULLONG':
240 elif value
== 'VIR_TYPED_PARAM_DOUBLE':
242 elif value
== 'VIR_TYPED_PARAM_BOOLEAN':
244 elif value
== 'VIR_DOMAIN_AFFECT_CURRENT':
246 elif value
== 'VIR_DOMAIN_AFFECT_LIVE':
248 elif value
== 'VIR_DOMAIN_AFFECT_CONFIG':
250 if onlyOverrides
and name
not in enums
[type]:
252 enums
[type][name
] = value
254 def lxc_enum(type, name
, value
):
255 if type not in lxc_enums
:
257 if onlyOverrides
and name
not in lxc_enums
[type]:
259 lxc_enums
[type][name
] = value
261 def qemu_enum(type, name
, value
):
262 if type not in qemu_enums
:
263 qemu_enums
[type] = {}
264 if onlyOverrides
and name
not in qemu_enums
[type]:
266 qemu_enums
[type][name
] = value
269 #######################################################################
271 # Some filtering rukes to drop functions/types which should not
272 # be exposed as-is on the Python interface
274 #######################################################################
276 functions_failed
= []
277 lxc_functions_failed
= []
278 qemu_functions_failed
= []
279 functions_skipped
= [
280 "virConnectListDomains",
282 lxc_functions_skipped
= []
283 qemu_functions_skipped
= []
289 # 'int *': "usually a return type",
290 'virConnectDomainEventCallback': "No function types in python",
291 'virConnectDomainEventGenericCallback': "No function types in python",
292 'virConnectDomainEventRTCChangeCallback': "No function types in python",
293 'virConnectDomainEventWatchdogCallback': "No function types in python",
294 'virConnectDomainEventIOErrorCallback': "No function types in python",
295 'virConnectDomainEventGraphicsCallback': "No function types in python",
296 'virConnectDomainQemuMonitorEventCallback': "No function types in python",
297 'virStreamEventCallback': "No function types in python",
298 'virEventHandleCallback': "No function types in python",
299 'virEventTimeoutCallback': "No function types in python",
300 'virDomainBlockJobInfoPtr': "Not implemented yet",
303 #######################################################################
305 # Table of remapping to/from the python type or class to the C
308 #######################################################################
311 'void': (None, None, None, None),
312 'int': ('i', None, "int", "int"),
313 'long': ('l', None, "long", "long"),
314 'double': ('d', None, "double", "double"),
315 'unsigned int': ('I', None, "int", "int"),
316 'unsigned long': ('l', None, "long", "long"),
317 'long long': ('L', None, "longlong", "long long"),
318 'unsigned long long': ('L', None, "longlong", "long long"),
319 'unsigned char *': ('z', None, "charPtr", "char *"),
320 'char *': ('z', None, "charPtr", "char *"),
321 'const char *': ('z', None, "constcharPtr", "const char *"),
322 'size_t': ('n', None, "size_t", "size_t"),
324 'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
325 'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
326 'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"),
328 'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
329 'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
330 'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"),
332 'virNetworkPortPtr': ('O', "virNetworkPort", "virNetworkPortPtr", "virNetworkPortPtr"),
333 'virNetworkPort *': ('O', "virNetworkPort", "virNetworkPortPtr", "virNetworkPortPtr"),
334 'const virNetworkPort *': ('O', "virNetworkPort", "virNetworkPortPtr", "virNetworkPortPtr"),
336 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
337 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
338 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"),
340 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
341 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
342 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"),
344 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
345 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
346 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"),
348 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
349 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
350 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"),
352 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
353 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
354 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"),
356 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
357 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
358 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"),
360 'virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
361 'virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
362 'const virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"),
364 'virNWFilterBindingPtr': ('O', "virNWFilterBinding", "virNWFilterBindingPtr", "virNWFilterBindingPtr"),
365 'virNWFilterBinding *': ('O', "virNWFilterBinding", "virNWFilterBindingPtr", "virNWFilterBindingPtr"),
366 'const virNWFilterBinding *': ('O', "virNWFilterBinding", "virNWFilterBindingPtr", "virNWFilterBindingPtr"),
368 'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
369 'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
370 'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
372 'virDomainCheckpointPtr': ('O', "virDomainCheckpoint", "virDomainCheckpointPtr", "virDomainCheckpointPtr"),
373 'virDomainCheckpoint *': ('O', "virDomainCheckpoint", "virDomainCheckpointPtr", "virDomainCheckpointPtr"),
374 'const virDomainCheckpoint *': ('O', "virDomainCheckpoint", "virDomainCheckpointPtr", "virDomainCheckpointPtr"),
376 'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
377 'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
378 'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
383 #######################################################################
385 # This part writes the C <-> Python stubs libvirt.[ch] and
386 # the table libvirt-export.c to add when registrering the Python module
388 #######################################################################
390 # Class methods which are written by hand in libvirt.c but the Python-level
391 # code is still automatically generated (so they are not in skip_function()).
393 'virConnectGetVersion',
394 'virConnectGetLibVersion',
395 'virConnectListDomainsID',
396 'virConnectListDefinedDomains',
397 'virConnectListNetworks',
398 'virConnectListDefinedNetworks',
399 'virConnectListSecrets',
400 'virConnectListInterfaces',
401 'virConnectListStoragePools',
402 'virConnectListDefinedStoragePools',
403 'virConnectListStorageVols',
404 'virConnectListDefinedStorageVols',
405 'virConnectListDefinedInterfaces',
406 'virConnectListNWFilters',
407 'virDomainSnapshotListNames',
408 'virDomainSnapshotListChildrenNames',
409 'virConnGetLastError',
413 'virDomainGetControlInfo',
414 'virDomainGetBlockInfo',
415 'virDomainGetJobInfo',
416 'virDomainGetJobStats',
418 'virNodeGetSecurityModel',
419 'virDomainGetSecurityLabel',
420 'virDomainGetSecurityLabelList',
422 'virDomainGetUUIDString',
423 'virDomainLookupByUUID',
425 'virNetworkGetUUIDString',
426 'virNetworkLookupByUUID',
427 'virDomainGetAutostart',
428 'virNetworkGetAutostart',
429 'virDomainBlockStats',
430 'virDomainInterfaceStats',
431 'virDomainMemoryStats',
432 'virNodeGetCellsFreeMemory',
433 'virDomainGetSchedulerType',
434 'virDomainGetSchedulerParameters',
435 'virDomainGetSchedulerParametersFlags',
436 'virDomainSetSchedulerParameters',
437 'virDomainSetSchedulerParametersFlags',
438 'virDomainSetBlkioParameters',
439 'virDomainGetBlkioParameters',
440 'virDomainSetMemoryParameters',
441 'virDomainGetMemoryParameters',
442 'virDomainSetNumaParameters',
443 'virDomainGetNumaParameters',
446 'virDomainPinVcpuFlags',
447 'virDomainGetVcpuPinInfo',
448 'virDomainGetEmulatorPinInfo',
449 'virDomainPinEmulator',
450 'virDomainGetIOThreadInfo',
451 'virDomainPinIOThread',
452 'virDomainSetIOThreadParams',
456 'virSecretGetUUIDString',
457 'virSecretLookupByUUID',
458 'virNWFilterGetUUID',
459 'virNWFilterGetUUIDString',
460 'virNWFilterLookupByUUID',
461 'virStoragePoolGetUUID',
462 'virStoragePoolGetUUIDString',
463 'virStoragePoolLookupByUUID',
464 'virStoragePoolGetInfo',
465 'virStorageVolGetInfo',
466 'virStorageVolGetInfoFlags',
467 'virStoragePoolGetAutostart',
468 'virStoragePoolListVolumes',
469 'virDomainBlockPeek',
470 'virDomainMemoryPeek',
471 'virEventRegisterImpl',
472 'virNodeListDevices',
473 'virNodeDeviceListCaps',
474 'virConnectBaselineCPU',
475 'virDomainRevertToSnapshot',
477 'virNodeGetCPUStats',
478 'virNodeGetMemoryStats',
479 'virDomainGetBlockJobInfo',
480 'virDomainMigrateGetCompressionCache',
481 'virDomainMigrateGetMaxSpeed',
482 'virDomainMigrateGetMaxDowntime',
483 'virDomainBlockStatsFlags',
484 'virDomainSetBlockIoTune',
485 'virDomainGetBlockIoTune',
486 'virDomainSetInterfaceParameters',
487 'virDomainGetInterfaceParameters',
488 'virDomainGetCPUStats',
489 'virDomainGetDiskErrors',
490 'virNodeGetMemoryParameters',
491 'virNodeSetMemoryParameters',
494 'virDomainMigrateToURI3',
495 'virConnectGetCPUModelNames',
496 'virNodeGetFreePages',
497 'virNetworkGetDHCPLeases',
498 'virDomainBlockCopy',
500 'virDomainGetFSInfo',
501 'virDomainInterfaceAddresses',
502 'virDomainGetPerfEvents',
503 'virDomainSetPerfEvents',
504 'virDomainGetGuestVcpus',
505 'virConnectBaselineHypervisorCPU',
506 'virDomainGetLaunchSecurityInfo',
508 'virNetworkPortGetParameters',
509 'virNetworkPortSetParameters',
513 'virDomainLxcOpenNamespace',
517 'virDomainQemuMonitorCommand',
518 'virDomainQemuAgentCommand',
522 # These are functions which the generator skips completly - no python
523 # or C code is generated. Generally should not be used for any more
524 # functions than those already listed
526 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons
527 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ?
528 'virResetError', # Not used in Python API XXX is this a bug ?
529 'virGetVersion', # Python C code is manually written
530 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons
531 'virConnCopyLastError', # Python API is called virConnGetLastError instead
532 'virCopyLastError', # Python API is called virGetLastError instead
533 'virConnectOpenAuth', # Python C code is manually written
534 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C
535 'virConnectDomainEventRegister', # overridden in virConnect.py
536 'virConnectDomainEventDeregister', # overridden in virConnect.py
537 'virConnectDomainEventRegisterAny', # overridden in virConnect.py
538 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py
539 'virConnectNetworkEventRegisterAny', # overridden in virConnect.py
540 'virConnectNetworkEventDeregisterAny', # overridden in virConnect.py
541 'virConnectStoragePoolEventRegisterAny', # overridden in virConnect.py
542 'virConnectStoragePoolEventDeregisterAny', # overridden in virConnect.py
543 'virConnectNodeDeviceEventRegisterAny', # overridden in virConnect.py
544 'virConnectNodeDeviceEventDeregisterAny', # overridden in virConnect.py
545 'virConnectSecretEventRegisterAny', # overridden in virConnect.py
546 'virConnectSecretEventDeregisterAny', # overridden in virConnect.py
547 'virSaveLastError', # We have our own python error wrapper
548 'virFreeError', # Only needed if we use virSaveLastError
549 'virConnectListAllDomains', # overridden in virConnect.py
550 'virDomainListAllCheckpoints', # overridden in virDomain.py
551 'virDomainCheckpointListAllChildren', # overridden in virDomainCheckpoint.py
552 'virDomainListAllSnapshots', # overridden in virDomain.py
553 'virDomainSnapshotListAllChildren', # overridden in virDomainSnapshot.py
554 'virConnectListAllStoragePools', # overridden in virConnect.py
555 'virStoragePoolListAllVolumes', # overridden in virStoragePool.py
556 'virConnectListAllNetworks', # overridden in virConnect.py
557 'virNetworkListAllPorts', # overridden in virConnect.py
558 'virConnectListAllInterfaces', # overridden in virConnect.py
559 'virConnectListAllNodeDevices', # overridden in virConnect.py
560 'virConnectListAllNWFilters', # overridden in virConnect.py
561 'virConnectListAllNWFilterBindings', # overridden in virConnect.py
562 'virConnectListAllSecrets', # overridden in virConnect.py
563 'virConnectGetAllDomainStats', # overridden in virConnect.py
564 'virDomainListGetStats', # overriden in virConnect.py
566 'virStreamRecvAll', # Pure python libvirt-override-virStream.py
567 'virStreamSendAll', # Pure python libvirt-override-virStream.py
568 'virStreamRecv', # overridden in libvirt-override-virStream.py
569 'virStreamSend', # overridden in libvirt-override-virStream.py
570 'virStreamRecvHole', # overridden in libvirt-override-virStream.py
571 'virStreamSendHole', # overridden in libvirt-override-virStream.py
572 'virStreamRecvFlags', # overridden in libvirt-override-virStream.py
573 'virStreamSparseRecvAll', # overridden in libvirt-override-virStream.py
574 'virStreamSparseSendAll', # overridden in libvirt-override-virStream.py
576 'virConnectUnregisterCloseCallback', # overridden in virConnect.py
577 'virConnectRegisterCloseCallback', # overridden in virConnect.py
579 'virDomainCreateXMLWithFiles', # overridden in virConnect.py
580 'virDomainCreateWithFiles', # overridden in virDomain.py
582 'virDomainFSFreeze', # overridden in virDomain.py
583 'virDomainFSThaw', # overridden in virDomain.py
584 'virDomainGetTime', # overridden in virDomain.py
585 'virDomainSetTime', # overridden in virDomain.py
587 # 'Ref' functions have no use for bindings users.
596 "virNWFilterBindingRef",
600 "virDomainCheckpointRef",
601 "virDomainSnapshotRef",
603 # This functions shouldn't be called via the bindings (and even the docs
604 # contain an explicit warning to that effect). The equivalent should be
605 # implemented in pure python for each class
606 "virDomainGetConnect",
607 "virInterfaceGetConnect",
608 "virNetworkGetConnect",
609 "virNetworkPortGetNetwork",
610 "virSecretGetConnect",
611 "virNWFilterGetConnect",
612 "virStoragePoolGetConnect",
613 "virStorageVolGetConnect",
614 "virDomainCheckpointGetConnect",
615 "virDomainCheckpointGetDomain",
616 "virDomainSnapshotGetConnect",
617 "virDomainSnapshotGetDomain",
619 # only useful in C code, python code uses dict for typed parameters
620 "virTypedParamsAddBoolean",
621 "virTypedParamsAddDouble",
622 "virTypedParamsAddFromString",
623 "virTypedParamsAddInt",
624 "virTypedParamsAddLLong",
625 "virTypedParamsAddString",
626 "virTypedParamsAddUInt",
627 "virTypedParamsAddULLong",
628 "virTypedParamsClear",
629 "virTypedParamsFree",
631 "virTypedParamsGetBoolean",
632 "virTypedParamsGetDouble",
633 "virTypedParamsGetInt",
634 "virTypedParamsGetLLong",
635 "virTypedParamsGetString",
636 "virTypedParamsGetUInt",
637 "virTypedParamsGetULLong",
639 'virNetworkDHCPLeaseFree', # only useful in C, python code uses list
640 'virDomainStatsRecordListFree', # only useful in C, python uses dict
641 'virDomainFSInfoFree', # only useful in C, python code uses list
642 'virDomainIOThreadInfoFree', # only useful in C, python code uses list
643 'virDomainInterfaceFree', # only useful in C, python code uses list
646 lxc_skip_function
= (
647 "virDomainLxcEnterNamespace",
648 "virDomainLxcEnterSecurityLabel",
650 qemu_skip_function
= (
651 #"virDomainQemuAttach",
652 'virConnectDomainQemuMonitorEventRegister', # overridden in -qemu.py
653 'virConnectDomainQemuMonitorEventDeregister', # overridden in -qemu.py
656 # Generate C code, but skip python impl
657 function_skip_python_impl
= (
658 "virStreamFree", # Needed in custom virStream __del__, but free shouldn't
659 # be exposed in bindings
662 lxc_function_skip_python_impl
= ()
663 qemu_function_skip_python_impl
= ()
665 function_skip_index_one
= (
666 "virDomainRevertToSnapshot",
669 def print_function_wrapper(module
, name
, output
, export
, include
):
674 global qemu_functions
675 global skipped_modules
676 global function_skip_python_impl
679 if module
== "libvirt":
680 (desc
, ret
, args
, file, mod
, cond
) = functions
[name
]
681 if module
== "libvirt-lxc":
682 (desc
, ret
, args
, file, mod
, cond
) = lxc_functions
[name
]
683 if module
== "libvirt-qemu":
684 (desc
, ret
, args
, file, mod
, cond
) = qemu_functions
[name
]
686 print("failed to get function %s infos" % name
)
689 if module
in skipped_modules
:
692 if module
== "libvirt":
693 if name
in skip_function
:
695 if name
in skip_impl
:
696 # Don't delete the function entry in the caller.
698 elif module
== "libvirt-lxc":
699 if name
in lxc_skip_function
:
701 if name
in lxc_skip_impl
:
702 # Don't delete the function entry in the caller.
704 elif module
== "libvirt-qemu":
705 if name
in qemu_skip_function
:
707 if name
in qemu_skip_impl
:
708 # Don't delete the function entry in the caller.
719 # This should be correct
720 if arg
[1][0:6] == "const ":
722 c_args
= c_args
+ " %s %s;\n" % (arg
[1], arg
[0])
723 if arg
[1] in py_types
:
724 (f
, t
, n
, c
) = py_types
[arg
[1]]
728 format_args
= format_args
+ ", &pyobj_%s" % (arg
[0])
729 c_args
= c_args
+ " PyObject *pyobj_%s;\n" % (arg
[0])
730 c_convert
= c_convert
+ \
731 " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg
[0],
734 format_args
= format_args
+ ", &%s" % (arg
[0])
736 format_args
= format_args
+ ", &py_buffsize%d" % num_bufs
737 c_args
= c_args
+ " int py_buffsize%d;\n" % num_bufs
738 num_bufs
= num_bufs
+ 1
740 c_call
= c_call
+ ", "
741 c_call
= c_call
+ "%s" % (arg
[0])
743 if arg
[1] in skipped_types
:
745 if arg
[1] in unknown_types
:
746 lst
= unknown_types
[arg
[1]]
749 unknown_types
[arg
[1]] = [name
]
752 format
= format
+ ":%s" % (name
)
755 if file == "python_accessor":
756 if args
[1][1] == "char *":
757 c_call
= "\n VIR_FREE(%s->%s);\n" % (
758 args
[0][0], args
[1][0], args
[0][0], args
[1][0])
759 c_call
= c_call
+ " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args
[0][0],
760 args
[1][0], args
[1][1], args
[1][0])
762 c_call
= "\n %s->%s = %s;\n" % (args
[0][0], args
[1][0],
765 c_call
= "\n %s(%s);\n" % (name
, c_call
)
766 ret_convert
= " Py_INCREF(Py_None);\n return Py_None;\n"
767 elif ret
[0] in py_types
:
768 (f
, t
, n
, c
) = py_types
[ret
[0]]
769 c_return
= " %s c_retval;\n" % (ret
[0])
770 if file == "python_accessor" and ret
[2] is not None:
771 c_call
= "\n c_retval = %s->%s;\n" % (args
[0][0], ret
[2])
773 c_call
= "\n c_retval = %s(%s);\n" % (name
, c_call
)
774 ret_convert
= " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n
,c
)
776 ret_convert
= ret_convert
+ " free(c_retval);\n"
777 ret_convert
= ret_convert
+ " return py_retval;\n"
779 if ret
[0] in skipped_types
:
781 if ret
[0] in unknown_types
:
782 lst
= unknown_types
[ret
[0]]
785 unknown_types
[ret
[0]] = [name
]
788 if cond
is not None and cond
!= "":
789 include
.write("#if %s\n" % cond
)
790 export
.write("#if %s\n" % cond
)
791 output
.write("#if %s\n" % cond
)
793 include
.write("PyObject * ")
794 if module
== "libvirt":
795 include
.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name
))
796 export
.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" %
798 elif module
== "libvirt-lxc":
799 include
.write("libvirt_lxc_%s(PyObject *self, PyObject *args);\n" % (name
))
800 export
.write(" { (char *)\"%s\", libvirt_lxc_%s, METH_VARARGS, NULL },\n" %
802 elif module
== "libvirt-qemu":
803 include
.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name
))
804 export
.write(" { (char *)\"%s\", libvirt_qemu_%s, METH_VARARGS, NULL },\n" %
808 # Those have been manually generated
809 if cond
is not None and cond
!= "":
810 include
.write("#endif\n")
811 export
.write("#endif\n")
812 output
.write("#endif\n")
814 if file == "python_accessor" and ret
[0] != "void" and ret
[2] is None:
815 # Those have been manually generated
816 if cond
is not None and cond
!= "":
817 include
.write("#endif\n")
818 export
.write("#endif\n")
819 output
.write("#endif\n")
822 output
.write("PyObject *\n")
823 if module
== "libvirt":
824 output
.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name
))
825 elif module
== "libvirt-lxc":
826 output
.write("libvirt_lxc_%s(PyObject *self ATTRIBUTE_UNUSED," % (name
))
827 elif module
== "libvirt-qemu":
828 output
.write("libvirt_qemu_%s(PyObject *self ATTRIBUTE_UNUSED," % (name
))
829 output
.write(" PyObject *args")
831 output
.write(" ATTRIBUTE_UNUSED")
832 output
.write(") {\n")
834 output
.write(" PyObject *py_retval;\n")
836 output
.write(c_return
)
840 output
.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" %
841 (format
, format_args
))
842 output
.write(" return NULL;\n")
844 output
.write(c_convert
+ "\n")
846 output
.write(" LIBVIRT_BEGIN_ALLOW_THREADS;")
848 output
.write(" LIBVIRT_END_ALLOW_THREADS;\n")
849 output
.write(ret_convert
)
850 output
.write("}\n\n")
851 if cond
is not None and cond
!= "":
852 include
.write("#endif /* %s */\n" % cond
)
853 export
.write("#endif /* %s */\n" % cond
)
854 output
.write("#endif /* %s */\n" % cond
)
856 if module
== "libvirt":
857 if name
in function_skip_python_impl
:
859 elif module
== "libvirt-lxc":
860 if name
in lxc_function_skip_python_impl
:
862 elif module
== "libvirt-qemu":
863 if name
in qemu_function_skip_python_impl
:
867 def print_c_pointer(classname
, output
, export
, include
):
868 output
.write("PyObject *\n")
869 output
.write("libvirt_%s_pointer(PyObject *self ATTRIBUTE_UNUSED, PyObject *args)\n" % classname
)
871 output
.write(" %sPtr ptr;\n" % classname
)
872 output
.write(" PyObject *pyptr;\n")
873 output
.write(" PyObject *pylong;\n")
875 output
.write(" if (!PyArg_ParseTuple(args, (char *) \"O\", &pyptr))\n")
876 output
.write(" return NULL;\n")
877 output
.write(" ptr = (%sPtr) Py%s_Get(pyptr);\n" % (classname
, classname
))
878 output
.write(" pylong = PyLong_FromVoidPtr(ptr);\n")
879 output
.write(" return pylong;\n")
883 include
.write("PyObject *libvirt_%s_pointer(PyObject *self, PyObject *args);\n" % classname
)
885 export
.write(" { (char *)\"%s_pointer\", libvirt_%s_pointer, METH_VARARGS, NULL },\n" %
886 (classname
, classname
))
888 def buildStubs(module
, api_xml
):
893 if module
not in ["libvirt", "libvirt-qemu", "libvirt-lxc"]:
894 print("ERROR: Unknown module type: %s" % module
)
897 if module
== "libvirt":
899 funcs_failed
= functions_failed
900 funcs_skipped
= functions_skipped
901 elif module
== "libvirt-lxc":
902 funcs
= lxc_functions
903 funcs_failed
= lxc_functions_failed
904 funcs_skipped
= lxc_functions_skipped
905 elif module
== "libvirt-qemu":
906 funcs
= qemu_functions
907 funcs_failed
= qemu_functions_failed
908 funcs_skipped
= qemu_functions_skipped
914 onlyOverrides
= False
915 (parser
, target
) = getparser()
919 msg
= sys
.exc_info()[1]
920 print(file, ":", msg
)
923 n
= len(list(funcs
.keys()))
925 print("Found %d functions in %s" % ((n
), api_xml
))
927 override_api_xml
= "%s-override-api.xml" % module
928 py_types
['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject")
931 f
= open(override_api_xml
)
935 (parser
, target
) = getparser()
939 msg
= sys
.exc_info()[1]
940 print(file, ":", msg
)
943 # XXX: This is not right, same function already in @functions
944 # will be overwritten.
945 print("Found %d functions in %s" % ((len(list(funcs
.keys())) - n
), override_api_xml
))
950 header_file
= "build/%s.h" % module
951 export_file
= "build/%s-export.c" % module
952 wrapper_file
= "build/%s.c" % module
954 include
= open(header_file
, "w")
955 include
.write("/* Generated by generator.py */\n\n")
957 export
= open(export_file
, "w")
958 export
.write("/* Generated by generator.py */\n\n")
960 wrapper
= open(wrapper_file
, "w")
961 wrapper
.write("/* Generated by generator.py */\n\n")
962 wrapper
.write("#include <Python.h>\n")
963 wrapper
.write("#include <libvirt/" + module
+ ".h>\n")
964 wrapper
.write("#include \"typewrappers.h\"\n")
965 wrapper
.write("#include \"build/" + module
+ ".h\"\n\n")
967 for function
in sorted(funcs
.keys()):
968 # Skip the functions which are not for the module
969 ret
= print_function_wrapper(module
, function
, wrapper
, export
, include
)
972 funcs_failed
.append(function
)
975 skipped
= skipped
+ 1
976 funcs_skipped
.append(function
)
979 nb_wrap
= nb_wrap
+ 1
981 if module
== "libvirt":
982 # Write C pointer conversion functions.
983 for classname
in primary_classes
:
984 print_c_pointer(classname
, wrapper
, export
, include
)
985 # Write define wrappers around event id enums, so that the
986 # preprocessor can see which enums were available.
987 for event_id
in event_ids
:
988 include
.write("#define %s %s\n" % (event_id
, event_id
))
995 print("Generated %d wrapper functions" % nb_wrap
)
998 print("Missing type converters: ")
999 for type in list(unknown_types
.keys()):
1000 print("%s:%d " % (type, len(unknown_types
[type])))
1002 for f
in funcs_failed
:
1003 print("ERROR: failed %s" % f
)
1007 if len(unknown_types
) > 0:
1011 #######################################################################
1013 # This part writes part of the Python front-end classes based on
1014 # mapping rules between types and classes and also based on function
1015 # renaming to get consistent function names at the Python level
1017 #######################################################################
1020 # The type automatically remapped to generated classes
1023 "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"),
1024 "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"),
1025 "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
1026 "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"),
1027 "virNetworkPortPtr": ("._o", "virNetworkPort(self, _obj=%s)", "virNetworkPort"),
1028 "virNetworkPort *": ("._o", "virNetworkPort(self, _obj=%s)", "virNetworkPort"),
1029 "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
1030 "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"),
1031 "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
1032 "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"),
1033 "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
1034 "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"),
1035 "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
1036 "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"),
1037 "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
1038 "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"),
1039 "virNWFilterPtr": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
1040 "virNWFilter *": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"),
1041 "virNWFilterBindingPtr": ("._o", "virNWFilterBinding(self, _obj=%s)", "virNWFilterBinding"),
1042 "virNWFilterBinding *": ("._o", "virNWFilterBinding(self, _obj=%s)", "virNWFilterBinding"),
1043 "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"),
1044 "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
1045 "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
1046 "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
1047 "virDomainCheckpointPtr": ("._o", "virDomainCheckpoint(self,_obj=%s)", "virDomainCheckpoint"),
1048 "virDomainCheckpoint *": ("._o", "virDomainCheckpoint(self, _obj=%s)", "virDomainCheckpoint"),
1049 "virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"),
1050 "virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"),
1053 primary_classes
= ["virDomain", "virNetwork", "virNetworkPort",
1054 "virInterface", "virStoragePool", "virStorageVol",
1055 "virConnect", "virNodeDevice", "virSecret",
1056 "virNWFilter", "virNWFilterBinding",
1057 "virStream", "virDomainCheckpoint", "virDomainSnapshot"]
1059 classes_destructors
= {
1060 "virDomain": "virDomainFree",
1061 "virNetwork": "virNetworkFree",
1062 "virNetworkPort": "virNetworkPortFree",
1063 "virInterface": "virInterfaceFree",
1064 "virStoragePool": "virStoragePoolFree",
1065 "virStorageVol": "virStorageVolFree",
1066 "virNodeDevice" : "virNodeDeviceFree",
1067 "virSecret": "virSecretFree",
1068 "virNWFilter": "virNWFilterFree",
1069 "virNWFilterBinding": "virNWFilterBindingFree",
1070 "virDomainCheckpoint": "virDomainCheckpointFree",
1071 "virDomainSnapshot": "virDomainSnapshotFree",
1072 # We hand-craft __del__ for this one
1073 #"virStream": "virStreamFree",
1076 class_skip_connect_impl
= {
1077 "virConnect" : True,
1080 class_domain_impl
= {
1081 "virDomainCheckpoint": True,
1082 "virDomainSnapshot": True,
1085 functions_noexcept
= {
1086 'virDomainGetID': True,
1087 'virDomainGetName': True,
1088 'virNetworkGetName': True,
1089 'virInterfaceGetName': True,
1090 'virStoragePoolGetName': True,
1091 'virStorageVolGetName': True,
1092 'virStorageVolGetkey': True,
1093 'virNodeDeviceGetName': True,
1094 'virNodeDeviceGetParent': True,
1095 'virSecretGetUsageType': True,
1096 'virSecretGetUsageID': True,
1097 'virNWFilterGetName': True,
1098 'virNWFilterBindingGetFilterName': True,
1099 'virNWFilterBindingGetPortDev': True,
1102 function_classes
= {}
1104 function_classes
["None"] = []
1106 # Functions returning an integral type which need special rules to
1107 # check for errors and raise exceptions.
1108 functions_int_exception_test
= {
1109 'virDomainGetMaxMemory': "%s == 0",
1111 functions_int_default_test
= "%s == -1"
1113 def is_integral_type (name
):
1114 return not re
.search ("^(unsigned)? ?(int|long)$", name
) is None
1116 def is_optional_arg(info
):
1117 return re
.search("^\(?optional\)?", info
) is not None
1119 def is_python_noninteger_type (name
):
1121 return name
[-1:] == "*"
1123 def nameFixup(name
, classe
, type, file):
1124 # avoid a disastrous clash
1125 listname
= classe
+ "List"
1128 if name
[0:l
] == listname
:
1130 func
= func
[0:1].lower() + func
[1:]
1131 elif name
[0:16] == "virNetworkDefine":
1133 func
= func
[0:1].lower() + func
[1:]
1134 elif name
[0:19] == "virNetworkCreateXML":
1136 func
= func
[0:1].lower() + func
[1:]
1137 elif name
[0:16] == "virNetworkLookup":
1139 func
= func
[0:1].lower() + func
[1:]
1140 elif name
[0:23] == "virNetworkPortCreateXML":
1142 func
= func
[0:1].lower() + func
[1:]
1143 elif name
[0:20] == "virNetworkPortLookup":
1145 func
= func
[0:1].lower() + func
[1:]
1146 elif name
[0:18] == "virInterfaceDefine":
1148 func
= func
[0:1].lower() + func
[1:]
1149 elif name
[0:21] == "virInterfaceCreateXML":
1151 func
= func
[0:1].lower() + func
[1:]
1152 elif name
[0:18] == "virInterfaceLookup":
1154 func
= func
[0:1].lower() + func
[1:]
1155 elif name
[0:15] == "virSecretDefine":
1157 func
= func
[0:1].lower() + func
[1:]
1158 elif name
[0:15] == "virSecretLookup":
1160 func
= func
[0:1].lower() + func
[1:]
1161 elif name
[0:27] == "virNWFilterBindingCreateXML":
1163 func
= func
[0:3].lower() + func
[3:]
1164 elif name
[0:24] == "virNWFilterBindingLookup":
1166 func
= func
[0:3].lower() + func
[3:]
1167 elif name
[0:24] == "virNWFilterBindingDefine":
1169 func
= func
[0:3].lower() + func
[3:]
1170 elif name
[0:24] == "virNWFilterBindingLookup":
1172 func
= func
[0:3].lower() + func
[3:]
1173 elif name
[0:17] == "virNWFilterDefine":
1175 func
= func
[0:3].lower() + func
[3:]
1176 elif name
[0:17] == "virNWFilterLookup":
1178 func
= func
[0:3].lower() + func
[3:]
1179 elif name
[0:20] == "virStoragePoolDefine":
1181 func
= func
[0:1].lower() + func
[1:]
1182 elif name
[0:23] == "virStoragePoolCreateXML":
1184 func
= func
[0:1].lower() + func
[1:]
1185 elif name
[0:20] == "virStoragePoolLookup":
1187 func
= func
[0:1].lower() + func
[1:]
1188 elif name
[0:19] == "virStorageVolDefine":
1190 func
= func
[0:1].lower() + func
[1:]
1191 elif name
[0:19] == "virStorageVolLookup":
1193 func
= func
[0:1].lower() + func
[1:]
1194 elif name
[0:20] == "virDomainGetCPUStats":
1196 func
= func
[0:1].lower() + func
[1:]
1197 elif name
[0:24] == "virDomainGetIOThreadInfo":
1199 func
= func
[0:2].lower() + func
[2:]
1200 elif name
[0:18] == "virDomainGetFSInfo":
1202 func
= func
[0:2].lower() + func
[2:]
1203 elif name
[0:12] == "virDomainGet":
1205 func
= func
[0:1].lower() + func
[1:]
1206 elif name
[0:31] == "virDomainCheckpointLookupByName":
1208 func
= func
[0:1].lower() + func
[1:]
1209 elif name
[0:28] == "virDomainCheckpointCreateXML":
1211 func
= func
[0:1].lower() + func
[1:]
1212 elif name
[0:19] == "virDomainCheckpoint":
1214 func
= func
[0:1].lower() + func
[1:]
1215 elif name
[0:29] == "virDomainSnapshotLookupByName":
1217 func
= func
[0:1].lower() + func
[1:]
1218 elif name
[0:26] == "virDomainSnapshotListNames":
1220 func
= func
[0:1].lower() + func
[1:]
1221 elif name
[0:28] == "virDomainSnapshotNumChildren":
1223 func
= func
[0:1].lower() + func
[1:]
1224 elif name
[0:20] == "virDomainSnapshotNum":
1226 func
= func
[0:1].lower() + func
[1:]
1227 elif name
[0:26] == "virDomainSnapshotCreateXML":
1229 func
= func
[0:1].lower() + func
[1:]
1230 elif name
[0:24] == "virDomainSnapshotCurrent":
1232 func
= func
[0:1].lower() + func
[1:]
1233 elif name
[0:17] == "virDomainSnapshot":
1235 func
= func
[0:1].lower() + func
[1:]
1236 elif name
[0:9] == "virDomain":
1238 func
= func
[0:1].lower() + func
[1:]
1239 elif name
[0:17] == "virNetworkPortGet":
1241 func
= func
[0:1].lower() + func
[1:]
1242 elif name
[0:13] == "virNetworkGet":
1244 func
= func
[0:1].lower() + func
[1:]
1245 func
= func
.replace("dHCP", "DHCP")
1246 elif name
[0:14] == "virNetworkPort":
1248 func
= func
[0:1].lower() + func
[1:]
1249 elif name
[0:10] == "virNetwork":
1251 func
= func
[0:1].lower() + func
[1:]
1252 elif name
[0:15] == "virInterfaceGet":
1254 func
= func
[0:1].lower() + func
[1:]
1255 elif name
[0:12] == "virInterface":
1257 func
= func
[0:1].lower() + func
[1:]
1258 elif name
[0:12] == 'virSecretGet':
1260 func
= func
[0:1].lower() + func
[1:]
1261 elif name
[0:9] == 'virSecret':
1263 func
= func
[0:1].lower() + func
[1:]
1264 elif name
[0:21] == 'virNWFilterBindingGet':
1266 func
= func
[0:1].lower() + func
[1:]
1267 elif name
[0:18] == 'virNWFilterBinding':
1269 func
= func
[0:1].lower() + func
[1:]
1270 elif name
[0:14] == 'virNWFilterGet':
1272 func
= func
[0:1].lower() + func
[1:]
1273 elif name
[0:11] == 'virNWFilter':
1275 func
= func
[0:1].lower() + func
[1:]
1276 elif name
[0:12] == 'virStreamNew':
1278 elif name
[0:9] == 'virStream':
1280 func
= func
[0:1].lower() + func
[1:]
1281 elif name
[0:17] == "virStoragePoolGet":
1283 func
= func
[0:1].lower() + func
[1:]
1284 elif name
[0:14] == "virStoragePool":
1286 func
= func
[0:1].lower() + func
[1:]
1287 elif name
[0:16] == "virStorageVolGet":
1289 func
= func
[0:1].lower() + func
[1:]
1290 elif name
[0:13] == "virStorageVol":
1292 func
= func
[0:1].lower() + func
[1:]
1293 elif name
[0:13] == "virNodeDevice":
1294 if name
[13:16] == "Get":
1295 func
= name
[16].lower() + name
[17:]
1296 elif name
[13:19] == "Lookup" or name
[13:19] == "Create":
1297 func
= name
[3].lower() + name
[4:]
1299 func
= name
[13].lower() + name
[14:]
1300 elif name
[0:7] == "virNode":
1302 func
= func
[0:1].lower() + func
[1:]
1303 elif name
[0:10] == "virConnect":
1305 func
= func
[0:1].lower() + func
[1:]
1306 elif name
[0:3] == "xml":
1308 func
= func
[0:1].lower() + func
[1:]
1315 if func
== "uUIDString":
1317 if func
== "oSType":
1319 if func
== "xMLDesc":
1321 if func
== "mACString":
1327 def functionSortKey(info
):
1328 (index
, func
, name
, ret
, args
, filename
, mod
) = info
1329 return func
, filename
1331 def writeDoc(module
, name
, args
, indent
, output
):
1332 if module
== "libvirt":
1334 elif module
== "libvirt-lxc":
1335 funcs
= lxc_functions
1336 elif module
== "libvirt-qemu":
1337 funcs
= qemu_functions
1338 if funcs
[name
][0] is None or funcs
[name
][0] == "":
1340 val
= funcs
[name
][0]
1341 val
= val
.replace("NULL", "None")
1342 output
.write(indent
)
1350 output
.write(indent
)
1352 output
.write(' """\n')
1354 def buildWrappers(module
):
1357 global unknown_types
1359 global function_classes
1362 global primary_classes
1363 global classes_destructors
1364 global functions_noexcept
1366 if not module
== "libvirt":
1367 print("ERROR: Unknown module type: %s" % module
)
1370 for type in list(classes_type
.keys()):
1371 function_classes
[classes_type
[type][2]] = []
1374 # Build the list of C types to look for ordered to start
1375 # with primary classes
1379 ctypes_processed
= {}
1380 classes_processed
= {}
1381 for classe
in primary_classes
:
1382 classes_list
.append(classe
)
1383 classes_processed
[classe
] = ()
1384 for type in list(classes_type
.keys()):
1385 tinfo
= classes_type
[type]
1386 if tinfo
[2] == classe
:
1388 ctypes_processed
[type] = ()
1389 for type in list(classes_type
.keys()):
1390 if type in ctypes_processed
:
1392 tinfo
= classes_type
[type]
1393 if tinfo
[2] not in classes_processed
:
1394 classes_list
.append(tinfo
[2])
1395 classes_processed
[tinfo
[2]] = ()
1398 ctypes_processed
[type] = ()
1400 for name
in list(functions
.keys()):
1402 (desc
, ret
, args
, file, mod
, cond
) = functions
[name
]
1404 classe
= classes_type
[type][2]
1406 if name
[0:3] == "vir" and len(args
) >= 1 and args
[0][1] == type:
1408 func
= nameFixup(name
, classe
, type, file)
1409 info
= (0, func
, name
, ret
, args
, file, mod
)
1410 function_classes
[classe
].append(info
)
1412 elif name
[0:3] == "vir" and len(args
) >= 2 and args
[1][1] == type \
1413 and file != "python_accessor" and not name
in function_skip_index_one
:
1415 func
= nameFixup(name
, classe
, type, file)
1416 info
= (1, func
, name
, ret
, args
, file, mod
)
1417 function_classes
[classe
].append(info
)
1421 func
= nameFixup(name
, "None", file, file)
1422 info
= (0, func
, name
, ret
, args
, file, mod
)
1423 function_classes
['None'].append(info
)
1425 classes_file
= "build/%s.py" % module
1426 extra_file
= "%s-override.py" % module
1429 classes
= open(classes_file
, "w")
1431 if os
.path
.exists(extra_file
):
1432 extra
= open(extra_file
, "r")
1433 classes
.write("#\n")
1434 classes
.write("# WARNING WARNING WARNING WARNING\n")
1435 classes
.write("#\n")
1436 classes
.write("# This file is automatically written by generator.py. Any changes\n")
1437 classes
.write("# made here will be lost.\n")
1438 classes
.write("#\n")
1439 classes
.write("# To change the manually written methods edit " + module
+ "-override.py\n")
1440 classes
.write("# To change the automatically written methods edit generator.py\n")
1441 classes
.write("#\n")
1442 classes
.write("# WARNING WARNING WARNING WARNING\n")
1443 classes
.write("#\n")
1444 if extra
is not None:
1445 classes
.writelines(extra
.readlines())
1446 classes
.write("#\n")
1447 classes
.write("# WARNING WARNING WARNING WARNING\n")
1448 classes
.write("#\n")
1449 classes
.write("# Automatically written part of python bindings for libvirt\n")
1450 classes
.write("#\n")
1451 classes
.write("# WARNING WARNING WARNING WARNING\n")
1452 if extra
is not None:
1455 if "None" in function_classes
:
1456 flist
= function_classes
["None"]
1457 flist
.sort(key
=functionSortKey
)
1460 (index
, func
, name
, ret
, args
, file, mod
) = info
1462 classes
.write("#\n# Functions from module %s\n#\n\n" % file)
1464 classes
.write("def %s(" % func
)
1469 classes
.write("%s" % arg
[0])
1470 if arg
[0] == "flags" or is_optional_arg(arg
[2]):
1471 if is_integral_type(arg
[1]):
1474 classes
.write("=None")
1476 classes
.write("):\n")
1477 writeDoc(module
, name
, args
, ' ', classes
)
1480 if arg
[1] in classes_type
:
1481 classes
.write(" if %s is None: %s__o = None\n" %
1483 classes
.write(" else: %s__o = %s%s\n" %
1484 (arg
[0], arg
[0], classes_type
[arg
[1]][0]))
1485 if ret
[0] != "void":
1486 classes
.write(" ret = ")
1489 classes
.write("libvirtmod.%s(" % name
)
1494 classes
.write("%s" % arg
[0])
1495 if arg
[1] in classes_type
:
1496 classes
.write("__o")
1498 classes
.write(")\n")
1500 if ret
[0] != "void":
1501 if ret
[0] in classes_type
:
1503 # Raise an exception
1505 if name
in functions_noexcept
:
1506 classes
.write(" if ret is None:return None\n")
1509 " if ret is None:raise libvirtError('%s() failed')\n" %
1512 classes
.write(" return ")
1513 classes
.write(classes_type
[ret
[0]][1] % ("ret"))
1516 # For functions returning an integral type there are
1517 # several things that we can do, depending on the
1518 # contents of functions_int_*:
1519 elif is_integral_type (ret
[0]):
1520 if name
not in functions_noexcept
:
1521 if name
in functions_int_exception_test
:
1522 test
= functions_int_exception_test
[name
]
1524 test
= functions_int_default_test
1525 classes
.write ((" if " + test
+
1526 ": raise libvirtError ('%s() failed')\n") %
1528 classes
.write(" return ret\n")
1530 elif is_python_noninteger_type (ret
[0]):
1531 if name
not in functions_noexcept
:
1532 classes
.write ((" if %s is None" +
1533 ": raise libvirtError ('%s() failed')\n") %
1535 classes
.write(" return ret\n")
1538 classes
.write(" return ret\n")
1542 for classname
in classes_list
:
1543 if classname
== "None":
1546 classes
.write("class %s(object):\n" % (classname
))
1547 if classname
in [ "virDomain", "virNetwork", "virInterface", "virStoragePool",
1548 "virStorageVol", "virNodeDevice", "virSecret","virStream",
1549 "virNWFilter", "virNWFilterBinding" ]:
1550 classes
.write(" def __init__(self, conn, _obj=None):\n")
1551 elif classname
in [ "virDomainCheckpoint", "virDomainSnapshot" ]:
1552 classes
.write(" def __init__(self, dom, _obj=None):\n")
1554 classes
.write(" def __init__(self, _obj=None):\n")
1555 if classname
in [ "virDomain", "virNetwork", "virInterface",
1556 "virNodeDevice", "virSecret", "virStream",
1557 "virNWFilter", "virNWFilterBinding" ]:
1558 classes
.write(" self._conn = conn\n")
1559 elif classname
in [ "virStorageVol", "virStoragePool" ]:
1560 classes
.write(" self._conn = conn\n" + \
1561 " if not isinstance(conn, virConnect):\n" + \
1562 " self._conn = conn._conn\n")
1563 elif classname
in [ "virDomainCheckpoint", "virDomainSnapshot" ]:
1564 classes
.write(" self._dom = dom\n")
1565 classes
.write(" self._conn = dom.connect()\n")
1566 classes
.write(" if type(_obj).__name__ not in [\"PyCapsule\", \"PyCObject\"]:\n")
1567 classes
.write(" raise Exception(\"Expected a wrapped C Object but got %s\" % type(_obj))\n")
1568 classes
.write(" self._o = _obj\n\n")
1570 if classname
in classes_destructors
:
1571 classes
.write(" def __del__(self):\n")
1572 classes
.write(" if self._o is not None:\n")
1573 classes
.write(" libvirtmod.%s(self._o)\n" %
1574 classes_destructors
[classname
])
1575 classes
.write(" self._o = None\n\n")
1576 destruct
=classes_destructors
[classname
]
1578 if classname
not in class_skip_connect_impl
:
1579 # Build python safe 'connect' method
1580 classes
.write(" def connect(self):\n")
1581 classes
.write(" return self._conn\n\n")
1583 if classname
in class_domain_impl
:
1584 classes
.write(" def domain(self):\n")
1585 classes
.write(" return self._dom\n\n")
1587 classes
.write(" def c_pointer(self):\n")
1588 classes
.write(" \"\"\"Get C pointer to underlying object\"\"\"\n")
1589 classes
.write(" return libvirtmod.%s_pointer(self._o)\n\n" %
1592 flist
= function_classes
[classname
]
1593 flist
.sort(key
=functionSortKey
)
1596 (index
, func
, name
, ret
, args
, file, mod
) = info
1598 # Do not provide as method the destructors for the class
1599 # to avoid double free
1601 if name
== destruct
:
1604 if file == "python_accessor":
1605 classes
.write(" # accessors for %s\n" % (classname
))
1607 classes
.write(" #\n")
1608 classes
.write(" # %s functions from module %s\n" % (
1610 classes
.write(" #\n\n")
1612 classes
.write(" def %s(self" % func
)
1616 classes
.write(", %s" % arg
[0])
1617 if arg
[0] == "flags" or is_optional_arg(arg
[2]):
1618 if is_integral_type(arg
[1]):
1621 classes
.write("=None")
1623 classes
.write("):\n")
1624 writeDoc(module
, name
, args
, ' ', classes
)
1627 if arg
[1] in classes_type
:
1629 classes
.write(" if %s is None: %s__o = None\n" %
1631 classes
.write(" else: %s__o = %s%s\n" %
1632 (arg
[0], arg
[0], classes_type
[arg
[1]][0]))
1634 if ret
[0] != "void":
1635 classes
.write(" ret = ")
1639 classes
.write("libvirtmod.%s(" % name
)
1644 classes
.write("%s" % arg
[0])
1645 if arg
[1] in classes_type
:
1646 classes
.write("__o")
1648 classes
.write("self")
1649 if arg
[1] in classes_type
:
1650 classes
.write(classes_type
[arg
[1]][0])
1652 classes
.write(")\n")
1654 if name
== "virConnectClose":
1655 classes
.write(" self._o = None\n")
1657 # For functions returning object types:
1658 if ret
[0] != "void":
1659 if ret
[0] in classes_type
:
1661 # Raise an exception
1663 if name
in functions_noexcept
:
1665 " if ret is None:return None\n")
1667 if classname
== "virConnect":
1669 " if ret is None:raise libvirtError('%s() failed', conn=self)\n" %
1671 elif classname
== "virDomain":
1673 " if ret is None:raise libvirtError('%s() failed', dom=self)\n" %
1675 elif classname
== "virNetwork":
1677 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1679 elif classname
== "virInterface":
1681 " if ret is None:raise libvirtError('%s() failed', net=self)\n" %
1683 elif classname
== "virStoragePool":
1685 " if ret is None:raise libvirtError('%s() failed', pool=self)\n" %
1687 elif classname
== "virStorageVol":
1689 " if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
1691 elif classname
in [ "virDomainCheckpoint", "virDomainSnapshot"]:
1693 " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" %
1697 " if ret is None:raise libvirtError('%s() failed')\n" %
1701 # generate the returned class wrapper for the object
1703 classes
.write(" __tmp = ")
1704 classes
.write(classes_type
[ret
[0]][1] % ("ret"))
1710 classes
.write(" return __tmp\n")
1712 # For functions returning an integral type there
1713 # are several things that we can do, depending on
1714 # the contents of functions_int_*:
1715 elif is_integral_type (ret
[0]):
1716 if name
not in functions_noexcept
:
1717 if name
in functions_int_exception_test
:
1718 test
= functions_int_exception_test
[name
]
1720 test
= functions_int_default_test
1721 if classname
== "virConnect":
1722 classes
.write ((" if " + test
+
1723 ": raise libvirtError ('%s() failed', conn=self)\n") %
1725 elif classname
== "virDomain":
1726 classes
.write ((" if " + test
+
1727 ": raise libvirtError ('%s() failed', dom=self)\n") %
1729 elif classname
== "virNetwork":
1730 classes
.write ((" if " + test
+
1731 ": raise libvirtError ('%s() failed', net=self)\n") %
1733 elif classname
== "virInterface":
1734 classes
.write ((" if " + test
+
1735 ": raise libvirtError ('%s() failed', net=self)\n") %
1737 elif classname
== "virStoragePool":
1738 classes
.write ((" if " + test
+
1739 ": raise libvirtError ('%s() failed', pool=self)\n") %
1741 elif classname
== "virStorageVol":
1742 classes
.write ((" if " + test
+
1743 ": raise libvirtError ('%s() failed', vol=self)\n") %
1746 classes
.write ((" if " + test
+
1747 ": raise libvirtError ('%s() failed')\n") %
1750 classes
.write (" return ret\n")
1752 elif is_python_noninteger_type (ret
[0]):
1753 if name
not in functions_noexcept
:
1754 if classname
== "virConnect":
1755 classes
.write ((" if %s is None" +
1756 ": raise libvirtError ('%s() failed', conn=self)\n") %
1758 elif classname
== "virDomain":
1759 classes
.write ((" if %s is None" +
1760 ": raise libvirtError ('%s() failed', dom=self)\n") %
1762 elif classname
== "virNetwork":
1763 classes
.write ((" if %s is None" +
1764 ": raise libvirtError ('%s() failed', net=self)\n") %
1766 elif classname
== "virInterface":
1767 classes
.write ((" if %s is None" +
1768 ": raise libvirtError ('%s() failed', net=self)\n") %
1770 elif classname
== "virStoragePool":
1771 classes
.write ((" if %s is None" +
1772 ": raise libvirtError ('%s() failed', pool=self)\n") %
1774 elif classname
== "virStorageVol":
1775 classes
.write ((" if %s is None" +
1776 ": raise libvirtError ('%s() failed', vol=self)\n") %
1779 classes
.write ((" if %s is None" +
1780 ": raise libvirtError ('%s() failed')\n") %
1783 classes
.write (" return ret\n")
1785 classes
.write(" return ret\n")
1788 # Append "<classname>.py" to class def, iff it exists
1791 extra
= open("libvirt-override-" + classname
+ ".py", "r")
1792 classes
.write (" #\n")
1793 classes
.write (" # %s methods from %s.py (hand coded)\n" % (classname
,classname
))
1794 classes
.write (" #\n")
1798 # Since we compile with older libvirt, we don't want to pull
1799 # in manually written python methods which call C methods
1800 # that don't exist. This code attempts to detect which
1801 # methods to skip by looking at the libvirtmod.XXXX calls
1803 def shouldSkip(lines
):
1805 offset
= line
.find("libvirtmod.")
1807 func
= line
[offset
+ 11:]
1808 offset
= func
.find("(")
1809 func
= func
[0:offset
]
1810 if func
not in functions_skipped
:
1814 for line
in extra
.readlines():
1815 offset
= line
.find(" def ")
1817 name
= line
[offset
+5:]
1818 offset
= name
.find("(")
1819 name
= name
[0:offset
]
1820 if cached
is not None:
1821 if not shouldSkip(cached
):
1822 classes
.writelines(cached
)
1823 if name
== "__del__":
1829 if cached
is not None:
1833 if not shouldSkip(cached
):
1834 classes
.writelines(cached
)
1841 # Generate enum constants
1843 def enumsSortKey(data
):
1848 value
= float('inf')
1849 return value
, data
[0]
1851 # Resolve only one level of reference
1852 def resolveEnum(enum
, data
):
1853 for name
,val
in enum
.items():
1857 enum
[name
] = data
[val
]
1860 enumvals
= list(enums
.items())
1861 # convert list of dicts to one dict
1863 for type,enum
in enumvals
:
1864 enumData
.update(enum
)
1866 if enumvals
is not None:
1867 enumvals
.sort(key
=lambda x
: x
[0])
1868 for type,enum
in enumvals
:
1869 classes
.write("# %s\n" % type)
1870 items
= list(resolveEnum(enum
, enumData
).items())
1871 items
.sort(key
=enumsSortKey
)
1872 if items
[-1][0].endswith('_LAST'):
1874 for name
,value
in items
:
1875 classes
.write("%s = %s\n" % (name
,value
))
1878 classes
.write("# typed parameter names\n")
1879 for name
, value
in params
:
1880 classes
.write("%s = \"%s\"\n" % (name
, value
))
1884 def qemuBuildWrappers(module
):
1885 global qemu_functions
1887 if not module
== "libvirt-qemu":
1888 print("ERROR: only libvirt-qemu is supported")
1891 extra_file
= "%s-override.py" % module
1894 fd
= open("build/libvirt_qemu.py", "w")
1896 if os
.path
.exists(extra_file
):
1897 extra
= open(extra_file
, "r")
1899 fd
.write("# WARNING WARNING WARNING WARNING\n")
1901 fd
.write("# This file is automatically written by generator.py. Any changes\n")
1902 fd
.write("# made here will be lost.\n")
1904 fd
.write("# To change the manually written methods edit " + module
+ "-override.py\n")
1905 fd
.write("# To change the automatically written methods edit generator.py\n")
1907 fd
.write("# WARNING WARNING WARNING WARNING\n")
1909 fd
.write("# Automatically written part of python bindings for libvirt\n")
1912 fd
.write("import sys\n")
1915 fd
.write(" import libvirtmod_qemu\n")
1916 fd
.write("except ImportError:\n")
1917 fd
.write(" lib_e = sys.exc_info()[1]\n")
1919 fd
.write(" import cygvirtmod_qemu as libvirtmod_qemu\n")
1920 fd
.write(" except ImportError:\n")
1921 fd
.write(" cyg_e = sys.exc_info()[1]\n")
1922 fd
.write(" if str(cyg_e).count(\"No module named\"):\n")
1923 fd
.write(" raise lib_e\n\n")
1925 fd
.write("import libvirt\n\n")
1926 fd
.write("# WARNING WARNING WARNING WARNING\n")
1928 if extra
is not None:
1929 fd
.writelines(extra
.readlines())
1931 if extra
is not None:
1934 fd
.write("# WARNING WARNING WARNING WARNING\n")
1936 fd
.write("#\n# Functions from module %s\n#\n\n" % module
)
1938 # Generate functions directly, no classes
1940 for name
in sorted(qemu_functions
.keys()):
1941 func
= nameFixup(name
, 'None', None, None)
1942 (desc
, ret
, args
, file, mod
, cond
) = qemu_functions
[name
]
1943 fd
.write("def %s(" % func
)
1948 fd
.write("%s" % arg
[0])
1951 writeDoc(module
, name
, args
, ' ', fd
)
1953 if ret
[0] != "void":
1957 fd
.write("libvirtmod_qemu.%s(" % name
)
1963 if arg
[1] == "virConnectPtr":
1968 if arg
[1] in ["virDomainPtr", "virConnectPtr"]:
1969 # FIXME: This might have problem if the function
1970 # has multiple args which are objects.
1971 fd
.write("%s.%s" % (arg
[0], "_o"))
1973 fd
.write("%s" % arg
[0])
1977 if ret
[0] != "void":
1978 fd
.write(" if ret is None: raise libvirt.libvirtError('" + name
+ "() failed')\n")
1979 if ret
[0] == "virDomainPtr":
1980 fd
.write(" __tmp = libvirt.virDomain(" + conn
+ ", _obj=ret)\n")
1981 fd
.write(" return __tmp\n")
1983 fd
.write(" return ret\n")
1988 # Generate enum constants
1990 for type,enum
in sorted(qemu_enums
.items()):
1991 fd
.write("# %s\n" % type)
1992 items
= list(enum
.items())
1993 items
.sort(key
=lambda i
: (int(i
[1]), i
[0]))
1994 for name
,value
in items
:
1995 fd
.write("%s = %s\n" % (name
,value
))
2001 def lxcBuildWrappers(module
):
2002 global lxc_functions
2004 if not module
== "libvirt-lxc":
2005 print("ERROR: only libvirt-lxc is supported")
2008 extra_file
= "%s-override.py" % module
2011 fd
= open("build/libvirt_lxc.py", "w")
2013 if os
.path
.exists(extra_file
):
2014 extra
= open(extra_file
, "r")
2016 fd
.write("# WARNING WARNING WARNING WARNING\n")
2018 fd
.write("# This file is automatically written by generator.py. Any changes\n")
2019 fd
.write("# made here will be lost.\n")
2021 fd
.write("# To change the manually written methods edit " + module
+ "-override.py\n")
2022 fd
.write("# To change the automatically written methods edit generator.py\n")
2024 fd
.write("# WARNING WARNING WARNING WARNING\n")
2026 if extra
is not None:
2027 fd
.writelines(extra
.readlines())
2029 fd
.write("# WARNING WARNING WARNING WARNING\n")
2031 fd
.write("# Automatically written part of python bindings for libvirt\n")
2033 fd
.write("# WARNING WARNING WARNING WARNING\n")
2034 if extra
is not None:
2037 fd
.write("import sys\n")
2040 fd
.write(" import libvirtmod_lxc\n")
2041 fd
.write("except ImportError:\n")
2042 fd
.write(" lib_e = sys.exc_info()[1]\n")
2044 fd
.write(" import cygvirtmod_lxc as libvirtmod_lxc\n")
2045 fd
.write(" except ImportError:\n")
2046 fd
.write(" cyg_e = sys.exc_info()[1]\n")
2047 fd
.write(" if str(cyg_e).count(\"No module named\"):\n")
2048 fd
.write(" raise lib_e\n\n")
2050 fd
.write("import libvirt\n\n")
2051 fd
.write("#\n# Functions from module %s\n#\n\n" % module
)
2053 # Generate functions directly, no classes
2055 for name
in sorted(lxc_functions
.keys()):
2056 func
= nameFixup(name
, 'None', None, None)
2057 (desc
, ret
, args
, file, mod
, cond
) = lxc_functions
[name
]
2058 fd
.write("def %s(" % func
)
2063 fd
.write("%s" % arg
[0])
2066 writeDoc(module
, name
, args
, ' ', fd
)
2068 if ret
[0] != "void":
2072 fd
.write("libvirtmod_lxc.%s(" % name
)
2078 if arg
[1] == "virConnectPtr":
2083 if arg
[1] in ["virDomainPtr", "virConnectPtr"]:
2084 # FIXME: This might have problem if the function
2085 # has multiple args which are objects.
2086 fd
.write("%s.%s" % (arg
[0], "_o"))
2088 fd
.write("%s" % arg
[0])
2092 if ret
[0] != "void":
2093 fd
.write(" if ret is None: raise libvirt.libvirtError('" + name
+ "() failed')\n")
2094 if ret
[0] == "virDomainPtr":
2095 fd
.write(" __tmp = libvirt.virDomain(" + conn
+ ", _obj=ret)\n")
2096 fd
.write(" return __tmp\n")
2098 fd
.write(" return ret\n")
2103 # Generate enum constants
2105 for type,enum
in sorted(lxc_enums
.items()):
2106 fd
.write("# %s\n" % type)
2107 items
= list(enum
.items())
2108 items
.sort(key
=lambda i
: (int(i
[1]), i
[0]))
2109 for name
,value
in items
:
2110 fd
.write("%s = %s\n" % (name
,value
))
2117 if not os
.path
.exists("build"):
2120 if buildStubs(sys
.argv
[1], sys
.argv
[2]) < 0:
2123 if sys
.argv
[1] == "libvirt":
2124 buildWrappers(sys
.argv
[1])
2125 elif sys
.argv
[1] == "libvirt-lxc":
2126 lxcBuildWrappers(sys
.argv
[1])
2127 elif sys
.argv
[1] == "libvirt-qemu":
2128 qemuBuildWrappers(sys
.argv
[1])
2130 print("ERROR: unknown module %s" % sys
.argv
[1])