2019-12-04 13:27:36 +03:00
#!/usr/bin/env python3
2005-12-19 19:34:11 +03:00
#
# generate python wrappers from the XML API description
#
2018-11-16 15:55:56 +03:00
import os
import re
import sys
import xml . sax
2018-11-20 14:07:44 +03:00
from contextlib import closing
2020-04-27 07:45:54 +03:00
from collections import defaultdict
2018-11-20 12:32:36 +03:00
from typing import Dict , IO , List , Optional , Set , Tuple , Union # noqa F401
ArgumentType = Tuple [ str , str , str ]
FunctionType = Tuple [ str , ArgumentType , List [ ArgumentType ] , str , str , str ]
EnumValue = Union [ str , int ]
EnumType = Dict [ str , EnumValue ]
functions = { } # type: Dict[str, FunctionType]
enums = defaultdict ( dict ) # type: Dict[str, EnumType] # { enumType: { enumConstant: enumValue } }
event_ids = [ ] # type: List[str]
params = [ ] # type: List[Tuple[str, str]] # [ (paramName, paramValue)... ]
2005-12-19 19:34:11 +03:00
2018-11-20 10:34:48 +03:00
quiet = True
2011-05-12 14:19:42 +04:00
2005-12-19 19:34:11 +03:00
#######################################################################
#
# That part if purely the API acquisition phase from the
2006-02-09 20:45:11 +03:00
# libvirt API description
2005-12-19 19:34:11 +03:00
#
#######################################################################
debug = 0
2013-11-22 18:09:55 +04:00
onlyOverrides = False
2024-04-26 17:56:43 +03:00
sourceDir = " . "
buildDir = " build "
2005-12-19 19:34:11 +03:00
2014-10-28 20:29:58 +03:00
libvirt_headers = [
" libvirt " ,
2016-04-21 15:43:29 +03:00
" libvirt-common " ,
2014-10-28 20:29:58 +03:00
" libvirt-domain " ,
2019-02-08 01:36:16 +03:00
" libvirt-domain-checkpoint " ,
2014-10-28 20:29:58 +03:00
" libvirt-domain-snapshot " ,
" libvirt-event " ,
" libvirt-host " ,
" libvirt-interface " ,
" libvirt-network " ,
" libvirt-nodedev " ,
" libvirt-nwfilter " ,
" libvirt-secret " ,
" libvirt-storage " ,
" libvirt-stream " ,
]
2024-04-26 17:56:43 +03:00
def openSourceFile ( file : str , mode : str = " r " , optional : bool = False ) :
path = os . path . join ( sourceDir , file )
if optional and not os . path . exists ( path ) :
return None
return open ( path , mode )
2018-11-20 10:34:48 +03:00
2018-11-20 12:32:36 +03:00
def parse ( data : IO [ str ] ) - > None :
2009-10-02 18:34:54 +04:00
target = docParser ( )
2018-11-20 14:07:44 +03:00
with closing ( xml . sax . make_parser ( ) ) as parser :
parser . setContentHandler ( target )
parser . parse ( data )
2005-12-19 19:34:11 +03:00
2018-11-20 10:34:48 +03:00
2009-10-02 19:20:47 +04:00
class docParser ( xml . sax . handler . ContentHandler ) :
2018-11-20 12:32:36 +03:00
def __init__ ( self ) - > None :
self . _data = [ ] # type: List[str]
2018-11-20 15:37:29 +03:00
self . in_function = False
2005-12-19 19:34:11 +03:00
2018-11-20 12:32:36 +03:00
def characters ( self , text : str ) - > None :
2005-12-19 19:34:11 +03:00
if debug :
2013-12-03 14:50:30 +04:00
print ( " data %s " % text )
2005-12-19 19:34:11 +03:00
self . _data . append ( text )
2018-11-20 12:32:36 +03:00
def startElement ( self , tag : str , attrs : Dict [ str , str ] ) - > None :
2005-12-19 19:34:11 +03:00
if debug :
2013-12-03 14:50:30 +04:00
print ( " start %s , %s " % ( tag , attrs ) )
2005-12-19 19:34:11 +03:00
if tag == ' function ' :
self . _data = [ ]
2018-11-20 15:37:29 +03:00
self . in_function = True
2018-11-20 16:04:20 +03:00
self . function_cond = ' '
2018-11-20 12:32:36 +03:00
self . function_args = [ ] # type: List[ArgumentType]
2018-11-20 16:04:20 +03:00
self . function_descr = ' '
2018-11-20 12:32:36 +03:00
self . function_return = None # type: Optional[ArgumentType]
2018-11-20 15:55:26 +03:00
self . function = attrs . get ( ' name ' , ' ' )
self . function_file = attrs . get ( ' file ' , ' ' )
self . function_module = attrs . get ( ' module ' , ' ' )
2005-12-19 19:34:11 +03:00
elif tag == ' cond ' :
self . _data = [ ]
elif tag == ' info ' :
self . _data = [ ]
elif tag == ' arg ' :
2018-11-20 15:37:29 +03:00
if self . in_function :
2018-11-20 15:55:26 +03:00
self . function_arg_name = attrs . get ( ' name ' , ' ' )
if self . function_arg_name == ' from ' :
self . function_arg_name = ' frm '
self . function_arg_type = attrs . get ( ' type ' , ' ' )
self . function_arg_info = attrs . get ( ' info ' , ' ' )
2005-12-19 19:34:11 +03:00
elif tag == ' return ' :
2018-11-20 15:37:29 +03:00
if self . in_function :
2018-11-20 15:55:26 +03:00
self . function_return_type = attrs . get ( ' type ' , ' ' )
self . function_return_info = attrs . get ( ' info ' , ' ' )
self . function_return_field = attrs . get ( ' field ' , ' ' )
2005-12-19 19:34:11 +03:00
elif tag == ' enum ' :
2013-02-05 16:55:09 +04:00
# enums come from header files, hence virterror.h
2022-03-24 15:23:46 +03:00
files = libvirt_headers + [ " virerror " ,
" virterror " ,
" libvirt-lxc " ,
" libvirt-qemu " ]
if attrs [ ' file ' ] in files :
2018-11-20 10:34:48 +03:00
enum ( attrs [ ' type ' ] , attrs [ ' name ' ] , attrs [ ' value ' ] )
2015-06-05 11:17:53 +03:00
elif tag == " macro " :
2018-11-20 13:29:12 +03:00
if " string " in attrs :
2015-06-05 11:17:53 +03:00
params . append ( ( attrs [ ' name ' ] , attrs [ ' string ' ] ) )
2005-12-19 19:34:11 +03:00
2018-11-20 12:32:36 +03:00
def endElement ( self , tag : str ) - > None :
2005-12-19 19:34:11 +03:00
if debug :
2013-12-03 14:50:30 +04:00
print ( " end %s " % tag )
2005-12-19 19:34:11 +03:00
if tag == ' function ' :
2020-07-17 11:28:39 +03:00
# functions come from source files, hence 'virerror.c'
2018-11-20 16:04:20 +03:00
if self . function :
assert self . function_return
2022-03-24 15:23:46 +03:00
modules = libvirt_headers + [ " event " ,
" virevent " ,
" virerror " ,
" virterror " ,
" libvirt-lxc " ,
" libvirt-qemu " ]
files = [ " python " , " python-lxc " , " python-qemu " ]
if ( self . function_module in modules or
self . function_file in files ) :
2011-09-09 15:09:44 +04:00
function ( self . function , self . function_descr ,
self . function_return , self . function_args ,
self . function_file , self . function_module ,
self . function_cond )
2018-11-20 15:37:29 +03:00
self . in_function = False
2005-12-19 19:34:11 +03:00
elif tag == ' arg ' :
2018-11-20 15:37:29 +03:00
if self . in_function :
2018-11-20 15:56:15 +03:00
self . function_args . append ( ( self . function_arg_name ,
2005-12-19 19:34:11 +03:00
self . function_arg_type ,
2018-11-20 15:56:15 +03:00
self . function_arg_info ) )
2005-12-19 19:34:11 +03:00
elif tag == ' return ' :
2018-11-20 15:37:29 +03:00
if self . in_function :
2018-11-20 15:56:15 +03:00
self . function_return = ( self . function_return_type ,
2005-12-19 19:34:11 +03:00
self . function_return_info ,
2018-11-20 15:56:15 +03:00
self . function_return_field )
2005-12-19 19:34:11 +03:00
elif tag == ' info ' :
2018-11-20 12:16:20 +03:00
str = ' ' . join ( self . _data )
2018-11-20 15:37:29 +03:00
if self . in_function :
2005-12-19 19:34:11 +03:00
self . function_descr = str
elif tag == ' cond ' :
2018-11-20 12:16:20 +03:00
str = ' ' . join ( self . _data )
2018-11-20 15:37:29 +03:00
if self . in_function :
2005-12-19 19:34:11 +03:00
self . function_cond = str
2008-02-05 22:27:37 +03:00
2018-11-20 12:32:36 +03:00
def function ( name : str , desc : str , ret : ArgumentType , args : List [ ArgumentType ] , file : str , module : str , cond : str ) - > None :
2013-11-22 18:09:55 +04:00
if onlyOverrides and name not in functions :
return
2013-11-27 02:37:05 +04:00
if name == " virConnectListDomains " :
name = " virConnectListDomainsID "
2011-09-09 15:09:44 +04:00
functions [ name ] = ( desc , ret , args , file , module , cond )
2018-11-20 10:34:48 +03:00
2018-11-20 12:32:36 +03:00
def enum ( type : str , name : str , value : EnumValue ) - > None :
2015-01-15 05:57:42 +03:00
if ( name . startswith ( ' VIR_DOMAIN_EVENT_ID_ ' ) or
2018-11-20 10:34:48 +03:00
name . startswith ( ' VIR_NETWORK_EVENT_ID_ ' ) ) :
2015-01-15 05:57:42 +03:00
event_ids . append ( name )
2011-05-17 21:44:53 +04:00
if value == ' VIR_TYPED_PARAM_INT ' :
value = 1
elif value == ' VIR_TYPED_PARAM_UINT ' :
value = 2
elif value == ' VIR_TYPED_PARAM_LLONG ' :
value = 3
elif value == ' VIR_TYPED_PARAM_ULLONG ' :
value = 4
elif value == ' VIR_TYPED_PARAM_DOUBLE ' :
value = 5
elif value == ' VIR_TYPED_PARAM_BOOLEAN ' :
value = 6
2011-06-08 10:33:33 +04:00
elif value == ' VIR_DOMAIN_AFFECT_CURRENT ' :
value = 0
elif value == ' VIR_DOMAIN_AFFECT_LIVE ' :
value = 1
elif value == ' VIR_DOMAIN_AFFECT_CONFIG ' :
value = 2
2022-03-24 15:23:46 +03:00
elif value == ' VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_BLOCK ' :
2019-11-28 11:35:57 +03:00
value = - 2
elif value == ' VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_DEFAULT ' :
value = - 1
elif value == ' VIR_DOMAIN_AGENT_RESPONSE_TIMEOUT_NOWAIT ' :
value = 0
2022-03-24 15:23:46 +03:00
2022-03-24 15:23:46 +03:00
if onlyOverrides and name not in enums [ type ] :
2013-11-22 18:09:55 +04:00
return
2022-03-24 15:23:46 +03:00
enums [ type ] [ name ] = value
2011-09-09 15:09:44 +04:00
2005-12-19 19:34:11 +03:00
#######################################################################
#
2020-07-17 11:28:39 +03:00
# Some filtering rules to drop functions/types which should not
2005-12-19 19:34:11 +03:00
# be exposed as-is on the Python interface
#
#######################################################################
skipped_types = {
2018-11-20 10:34:48 +03:00
# 'int *': "usually a return type",
' virConnectDomainEventCallback ' : " No function types in python " ,
' virConnectDomainEventGenericCallback ' : " No function types in python " ,
' virConnectDomainEventRTCChangeCallback ' : " No function types in python " ,
' virConnectDomainEventWatchdogCallback ' : " No function types in python " ,
' virConnectDomainEventIOErrorCallback ' : " No function types in python " ,
' virConnectDomainEventGraphicsCallback ' : " No function types in python " ,
' virConnectDomainQemuMonitorEventCallback ' : " No function types in python " ,
' virStreamEventCallback ' : " No function types in python " ,
' virEventHandleCallback ' : " No function types in python " ,
' virEventTimeoutCallback ' : " No function types in python " ,
' virDomainBlockJobInfoPtr ' : " Not implemented yet " ,
2005-12-19 19:34:11 +03:00
}
#######################################################################
#
# Table of remapping to/from the python type or class to the C
# counterpart.
#
#######################################################################
py_types = {
2020-04-23 08:41:04 +03:00
' void ' : ( ' ' , ' ' , ' ' , ' ' ) ,
' int ' : ( ' i ' , ' ' , " int " , " int " ) ,
' long ' : ( ' l ' , ' ' , " long " , " long " ) ,
' double ' : ( ' d ' , ' ' , " double " , " double " ) ,
' unsigned int ' : ( ' I ' , ' ' , " int " , " int " ) ,
' unsigned long ' : ( ' l ' , ' ' , " long " , " long " ) ,
' long long ' : ( ' L ' , ' ' , " longlong " , " long long " ) ,
' unsigned long long ' : ( ' L ' , ' ' , " longlong " , " long long " ) ,
' unsigned char * ' : ( ' z ' , ' ' , " charPtr " , " char * " ) ,
' char * ' : ( ' z ' , ' ' , " charPtr " , " char * " ) ,
' const char * ' : ( ' z ' , ' ' , " constcharPtr " , " const char * " ) ,
' size_t ' : ( ' n ' , ' ' , " size_t " , " size_t " ) ,
2008-02-20 18:26:22 +03:00
2018-11-20 10:34:48 +03:00
' virDomainPtr ' : ( ' O ' , " virDomain " , " virDomainPtr " , " virDomainPtr " ) ,
' virDomain * ' : ( ' O ' , " virDomain " , " virDomainPtr " , " virDomainPtr " ) ,
' const virDomain * ' : ( ' O ' , " virDomain " , " virDomainPtr " , " virDomainPtr " ) ,
2008-02-20 18:26:22 +03:00
2018-11-20 10:34:48 +03:00
' virNetworkPtr ' : ( ' O ' , " virNetwork " , " virNetworkPtr " , " virNetworkPtr " ) ,
' virNetwork * ' : ( ' O ' , " virNetwork " , " virNetworkPtr " , " virNetworkPtr " ) ,
' const virNetwork * ' : ( ' O ' , " virNetwork " , " virNetworkPtr " , " virNetworkPtr " ) ,
2008-02-20 18:26:22 +03:00
2018-11-20 10:34:48 +03:00
' virNetworkPortPtr ' : ( ' O ' , " virNetworkPort " , " virNetworkPortPtr " , " virNetworkPortPtr " ) ,
' virNetworkPort * ' : ( ' O ' , " virNetworkPort " , " virNetworkPortPtr " , " virNetworkPortPtr " ) ,
' const virNetworkPort * ' : ( ' O ' , " virNetworkPort " , " virNetworkPortPtr " , " virNetworkPortPtr " ) ,
2019-06-18 14:08:32 +03:00
2018-11-20 10:34:48 +03:00
' virInterfacePtr ' : ( ' O ' , " virInterface " , " virInterfacePtr " , " virInterfacePtr " ) ,
' virInterface * ' : ( ' O ' , " virInterface " , " virInterfacePtr " , " virInterfacePtr " ) ,
' const virInterface * ' : ( ' O ' , " virInterface " , " virInterfacePtr " , " virInterfacePtr " ) ,
2009-05-21 14:57:05 +04:00
2018-11-20 10:34:48 +03:00
' virStoragePoolPtr ' : ( ' O ' , " virStoragePool " , " virStoragePoolPtr " , " virStoragePoolPtr " ) ,
' virStoragePool * ' : ( ' O ' , " virStoragePool " , " virStoragePoolPtr " , " virStoragePoolPtr " ) ,
' const virStoragePool * ' : ( ' O ' , " virStoragePool " , " virStoragePoolPtr " , " virStoragePoolPtr " ) ,
2008-02-20 18:26:22 +03:00
2018-11-20 10:34:48 +03:00
' virStorageVolPtr ' : ( ' O ' , " virStorageVol " , " virStorageVolPtr " , " virStorageVolPtr " ) ,
' virStorageVol * ' : ( ' O ' , " virStorageVol " , " virStorageVolPtr " , " virStorageVolPtr " ) ,
' const virStorageVol * ' : ( ' O ' , " virStorageVol " , " virStorageVolPtr " , " virStorageVolPtr " ) ,
2008-02-20 18:26:22 +03:00
2018-11-20 10:34:48 +03:00
' virConnectPtr ' : ( ' O ' , " virConnect " , " virConnectPtr " , " virConnectPtr " ) ,
' virConnect * ' : ( ' O ' , " virConnect " , " virConnectPtr " , " virConnectPtr " ) ,
' const virConnect * ' : ( ' O ' , " virConnect " , " virConnectPtr " , " virConnectPtr " ) ,
2008-11-21 15:41:15 +03:00
2018-11-20 10:34:48 +03:00
' 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-04 22:38:21 +04:00
2018-11-20 10:34:48 +03:00
' virSecretPtr ' : ( ' O ' , " virSecret " , " virSecretPtr " , " virSecretPtr " ) ,
' virSecret * ' : ( ' O ' , " virSecret " , " virSecretPtr " , " virSecretPtr " ) ,
' const virSecret * ' : ( ' O ' , " virSecret " , " virSecretPtr " , " virSecretPtr " ) ,
2009-07-10 15:18:12 +04:00
2018-11-20 10:34:48 +03:00
' virNWFilterPtr ' : ( ' O ' , " virNWFilter " , " virNWFilterPtr " , " virNWFilterPtr " ) ,
' virNWFilter * ' : ( ' O ' , " virNWFilter " , " virNWFilterPtr " , " virNWFilterPtr " ) ,
' const virNWFilter * ' : ( ' O ' , " virNWFilter " , " virNWFilterPtr " , " virNWFilterPtr " ) ,
2010-04-29 14:46:01 +04:00
2018-11-20 10:34:48 +03:00
' virNWFilterBindingPtr ' : ( ' O ' , " virNWFilterBinding " , " virNWFilterBindingPtr " , " virNWFilterBindingPtr " ) ,
' virNWFilterBinding * ' : ( ' O ' , " virNWFilterBinding " , " virNWFilterBindingPtr " , " virNWFilterBindingPtr " ) ,
' const virNWFilterBinding * ' : ( ' O ' , " virNWFilterBinding " , " virNWFilterBindingPtr " , " virNWFilterBindingPtr " ) ,
2018-06-26 13:18:32 +03:00
2018-11-20 10:34:48 +03:00
' virStreamPtr ' : ( ' O ' , " virStream " , " virStreamPtr " , " virStreamPtr " ) ,
' virStream * ' : ( ' O ' , " virStream " , " virStreamPtr " , " virStreamPtr " ) ,
' const virStream * ' : ( ' O ' , " virStream " , " virStreamPtr " , " virStreamPtr " ) ,
2010-04-01 00:33:13 +04:00
2018-11-20 10:34:48 +03:00
' virDomainCheckpointPtr ' : ( ' O ' , " virDomainCheckpoint " , " virDomainCheckpointPtr " , " virDomainCheckpointPtr " ) ,
' virDomainCheckpoint * ' : ( ' O ' , " virDomainCheckpoint " , " virDomainCheckpointPtr " , " virDomainCheckpointPtr " ) ,
' const virDomainCheckpoint * ' : ( ' O ' , " virDomainCheckpoint " , " virDomainCheckpointPtr " , " virDomainCheckpointPtr " ) ,
2019-02-08 01:36:16 +03:00
2018-11-20 10:34:48 +03:00
' virDomainSnapshotPtr ' : ( ' O ' , " virDomainSnapshot " , " virDomainSnapshotPtr " , " virDomainSnapshotPtr " ) ,
' virDomainSnapshot * ' : ( ' O ' , " virDomainSnapshot " , " virDomainSnapshotPtr " , " virDomainSnapshotPtr " ) ,
' const virDomainSnapshot * ' : ( ' O ' , " virDomainSnapshot " , " virDomainSnapshotPtr " , " virDomainSnapshotPtr " ) ,
2018-11-20 12:32:36 +03:00
} # type: Dict[str, Tuple[str, str, str, str]]
2005-12-19 19:34:11 +03:00
#######################################################################
#
2009-09-16 17:03:53 +04:00
# This part writes the C <-> Python stubs libvirt.[ch] and
2024-04-26 18:43:50 +03:00
# the table libvirt-export.c.inc to add when registering the Python module
2005-12-19 19:34:11 +03:00
#
#######################################################################
2012-09-04 19:16:24 +04:00
# Class methods which are written by hand in libvirt.c but the Python-level
2005-12-19 19:34:11 +03:00
# code is still automatically generated (so they are not in skip_function()).
2020-04-23 08:39:04 +03:00
skip_impl = {
2010-01-22 13:01:09 +03:00
' virConnectGetVersion ' ,
2009-11-12 18:53:26 +03:00
' virConnectGetLibVersion ' ,
2006-01-31 13:24:12 +03:00
' virConnectListDomainsID ' ,
2006-11-16 03:17:10 +03:00
' virConnectListDefinedDomains ' ,
2007-03-09 18:42:50 +03: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-04 22:38:21 +04:00
' virConnectListSecrets ' ,
2009-11-20 18:22:42 +03:00
' virConnectListInterfaces ' ,
2008-02-20 18:26:22 +03:00
' virConnectListStoragePools ' ,
' virConnectListDefinedStoragePools ' ,
' virConnectListStorageVols ' ,
' virConnectListDefinedStorageVols ' ,
2009-11-20 18:22:42 +03:00
' virConnectListDefinedInterfaces ' ,
2010-03-25 20:46:09 +03:00
' virConnectListNWFilters ' ,
2010-04-20 13:49:27 +04:00
' virDomainSnapshotListNames ' ,
2011-09-25 05:56:26 +04:00
' virDomainSnapshotListChildrenNames ' ,
2006-11-08 02:18:56 +03:00
' virConnGetLastError ' ,
' virGetLastError ' ,
2006-01-31 13:24:12 +03:00
' virDomainGetInfo ' ,
2011-04-22 15:31:35 +04:00
' virDomainGetState ' ,
2011-05-24 12:28:50 +04:00
' virDomainGetControlInfo ' ,
2010-04-28 16:42:13 +04:00
' virDomainGetBlockInfo ' ,
2010-02-03 14:31:45 +03:00
' virDomainGetJobInfo ' ,
2013-01-26 03:30:49 +04:00
' virDomainGetJobStats ' ,
2006-03-29 16:46:03 +04:00
' virNodeGetInfo ' ,
2013-11-26 22:31:18 +04:00
' virNodeGetSecurityModel ' ,
' virDomainGetSecurityLabel ' ,
' virDomainGetSecurityLabelList ' ,
2006-02-23 14:26:17 +03:00
' virDomainGetUUID ' ,
2008-06-10 19:20:25 +04:00
' virDomainGetUUIDString ' ,
2006-02-24 15:26:56 +03:00
' virDomainLookupByUUID ' ,
2007-03-09 18:42:50 +03:00
' virNetworkGetUUID ' ,
2008-06-10 19:20:25 +04:00
' virNetworkGetUUIDString ' ,
2007-03-09 18:42:50 +03:00
' virNetworkLookupByUUID ' ,
2020-01-02 18:46:43 +03:00
' virNetworkPortGetUUID ' ,
' virNetworkPortGetUUIDString ' ,
' virNetworkPortLookupByUUID ' ,
2008-01-21 18:55:53 +03:00
' virDomainGetAutostart ' ,
' virNetworkGetAutostart ' ,
2007-10-01 00:52:13 +04:00
' virDomainBlockStats ' ,
' virDomainInterfaceStats ' ,
2009-12-20 15:48:37 +03:00
' virDomainMemoryStats ' ,
2007-12-07 11:41:01 +03:00
' virNodeGetCellsFreeMemory ' ,
2008-01-21 18:41:15 +03:00
' virDomainGetSchedulerType ' ,
' virDomainGetSchedulerParameters ' ,
2011-05-18 01:17:14 +04:00
' virDomainGetSchedulerParametersFlags ' ,
2008-01-21 18:41:15 +03:00
' virDomainSetSchedulerParameters ' ,
2011-05-17 10:20:00 +04:00
' virDomainSetSchedulerParametersFlags ' ,
2011-02-22 08:30:33 +03:00
' virDomainSetBlkioParameters ' ,
' virDomainGetBlkioParameters ' ,
2010-10-12 17:43:27 +04:00
' virDomainSetMemoryParameters ' ,
' virDomainGetMemoryParameters ' ,
2011-12-20 12:35:00 +04:00
' virDomainSetNumaParameters ' ,
' virDomainGetNumaParameters ' ,
2008-01-21 18:41:15 +03:00
' virDomainGetVcpus ' ,
' virDomainPinVcpu ' ,
2011-07-25 11:00:11 +04:00
' virDomainPinVcpuFlags ' ,
2011-07-25 11:04:50 +04:00
' virDomainGetVcpuPinInfo ' ,
2013-03-20 14:43:41 +04:00
' virDomainGetEmulatorPinInfo ' ,
' virDomainPinEmulator ' ,
2015-03-26 14:22:13 +03:00
' virDomainGetIOThreadInfo ' ,
Support virDomainPinIOThread
Support the libvirt_virDomainSetIOThreads method using code that mimics
the existing libvirt_virDomainPinVcpuFlags method
The following is a sample session assuming guest 'iothr-gst' has IOThreads
configured (it's currently running, too)
>>> import libvirt
>>> con=libvirt.open("qemu:///system")
>>> dom=con.lookupByName('iothr-gst')
>>> dom.ioThreadsInfo()
[(1, [False, False, True, False]), (2, [False, False, False, True]), (3, [True, True, True, True])]
>>> cpumap=(True,True,True,False)
>>> dom.pinIOThread(3,cpumap)
0
>>> print dom.ioThreadsInfo()
[(1, [False, False, True, False]), (2, [False, False, False, True]), (3, [True, True, True, False])]
>>>
merge
2015-02-19 04:27:07 +03:00
' virDomainPinIOThread ' ,
2018-11-20 19:09:43 +03:00
' virDomainSetIOThreadParams ' ,
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-04 22:38:21 +04: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-10 20:44:12 +04:00
' virSecretGetUUID ' ,
' virSecretGetUUIDString ' ,
' virSecretLookupByUUID ' ,
2010-04-29 14:46:01 +04:00
' virNWFilterGetUUID ' ,
' virNWFilterGetUUIDString ' ,
' virNWFilterLookupByUUID ' ,
2008-02-20 18:26:22 +03:00
' virStoragePoolGetUUID ' ,
2008-06-10 19:20:25 +04:00
' virStoragePoolGetUUIDString ' ,
2008-02-20 18:26:22 +03:00
' virStoragePoolLookupByUUID ' ,
' virStoragePoolGetInfo ' ,
' virStorageVolGetInfo ' ,
2016-12-21 16:16:37 +03:00
' virStorageVolGetInfoFlags ' ,
2008-02-20 18:26:22 +03:00
' virStoragePoolGetAutostart ' ,
' virStoragePoolListVolumes ' ,
2008-07-25 16:37:06 +04:00
' virDomainBlockPeek ' ,
' virDomainMemoryPeek ' ,
2008-10-31 13:13:45 +03:00
' virEventRegisterImpl ' ,
2008-11-21 15:41:15 +03:00
' virNodeListDevices ' ,
' virNodeDeviceListCaps ' ,
2010-01-22 16:52:41 +03:00
' virConnectBaselineCPU ' ,
2010-05-19 17:02:30 +04:00
' virDomainRevertToSnapshot ' ,
2011-06-07 13:11:12 +04:00
' virDomainSendKey ' ,
2011-06-07 04:58:47 +04:00
' virNodeGetCPUStats ' ,
2011-06-07 05:03:36 +04:00
' virNodeGetMemoryStats ' ,
2011-07-22 09:43:53 +04:00
' virDomainGetBlockJobInfo ' ,
2013-02-18 20:31:08 +04:00
' virDomainMigrateGetCompressionCache ' ,
2011-08-26 22:10:21 +04:00
' virDomainMigrateGetMaxSpeed ' ,
2017-08-26 15:58:41 +03:00
' virDomainMigrateGetMaxDowntime ' ,
2011-09-05 12:24:21 +04:00
' virDomainBlockStatsFlags ' ,
2011-11-15 13:02:49 +04:00
' virDomainSetBlockIoTune ' ,
' virDomainGetBlockIoTune ' ,
2011-12-29 11:33:16 +04:00
' virDomainSetInterfaceParameters ' ,
' virDomainGetInterfaceParameters ' ,
2012-03-20 08:34:06 +04:00
' virDomainGetCPUStats ' ,
2012-01-31 10:41:53 +04:00
' virDomainGetDiskErrors ' ,
2012-09-14 18:42:14 +04:00
' virNodeGetMemoryParameters ' ,
' virNodeSetMemoryParameters ' ,
2019-09-16 19:37:13 +03:00
' virConnectSetIdentity ' ,
2012-10-24 00:34:53 +04:00
' virNodeGetCPUMap ' ,
2013-05-07 16:29:19 +04:00
' virDomainMigrate3 ' ,
' virDomainMigrateToURI3 ' ,
2013-11-21 18:47:08 +04:00
' virConnectGetCPUModelNames ' ,
Implement new virNodeGetFreePages API
The API expose information on host's free pages counts. For easier
access, in python this API returns a dictionary such as:
In [4]: conn.getFreePages([2048,1*1024*1024], -1, 5)
Out[4]:
{-1: {2048: 114, 1048576: 4},
0: {2048: 3, 1048576: 1},
1: {2048: 100, 1048576: 1},
2: {2048: 10, 1048576: 1},
3: {2048: 1, 1048576: 1}}
At the top level of the returned dictionary there's a pair of <NUMA
node> and another dictionary that contains detailed information on
each supported page size. The information then consists of fairs of
<page size> and <count of free pages>.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
2014-06-20 11:08:39 +04:00
' virNodeGetFreePages ' ,
Implement new virNetworkGetDHCPLeases API
This API returns a list of DHCP leases for all network interfaces
connected to the given virtual network or limited output just for one
interface if mac is specified.
Example Output:
[{'iface': 'virbr3', 'ipaddr': '192.168.150.181', 'hostname': 'ubuntu14',
'expirytime': 1403737495L, 'prefix': 24, 'clientid': None,
'mac': '52:54:00:e8:73:eb', 'iaid': None, 'type': 0},
{'iface': 'virbr3', 'ipaddr': '2001:db8:ca2:2:1::bd', 'hostname': 'fedora20-test',
'expirytime': 1403738587L, 'prefix': 64, 'clientid': '00:04:b1:d8:86:42:e1:6a:aa:cf:d5:86:94:23:6f:94:04:cd',
'mac': '52:54:00:5b:40:98', 'iaid': '5980312', 'type': 1}]
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
2014-06-26 02:45:30 +04:00
' virNetworkGetDHCPLeases ' ,
2014-09-01 23:58:48 +04:00
' virDomainBlockCopy ' ,
2014-09-25 19:02:49 +04:00
' virNodeAllocPages ' ,
2014-11-22 04:28:00 +03:00
' virDomainGetFSInfo ' ,
2015-03-28 13:21:56 +03:00
' virDomainInterfaceAddresses ' ,
2016-03-30 05:13:19 +03:00
' virDomainGetPerfEvents ' ,
' virDomainSetPerfEvents ' ,
2016-06-23 07:55:55 +03:00
' virDomainGetGuestVcpus ' ,
2018-05-31 18:14:25 +03:00
' virConnectBaselineHypervisorCPU ' ,
2018-06-12 17:06:23 +03:00
' virDomainGetLaunchSecurityInfo ' ,
2022-01-05 19:32:07 +03:00
' virDomainSetLaunchSecurityState ' ,
2018-06-12 17:17:58 +03:00
' virNodeGetSEVInfo ' ,
2019-06-18 14:08:32 +03:00
' virNetworkPortGetParameters ' ,
' virNetworkPortSetParameters ' ,
2019-08-28 16:36:12 +03:00
' virDomainGetGuestInfo ' ,
2020-11-19 19:30:14 +03:00
' virDomainAuthorizedSSHKeysGet ' ,
' virDomainAuthorizedSSHKeysSet ' ,
2021-02-15 18:16:59 +03:00
' virDomainGetMessages ' ,
2021-09-21 22:08:46 +03:00
' virNodeDeviceGetAutostart ' ,
2022-05-12 11:46:34 +03:00
' virDomainSaveParams ' ,
' virDomainRestoreParams ' ,
2005-12-19 19:34:11 +03:00
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 17:15:19 +04:00
' virDomainLxcOpenNamespace ' ,
2011-09-09 15:09:44 +04:00
' virDomainQemuMonitorCommand ' ,
2012-08-23 07:29:23 +04:00
' virDomainQemuAgentCommand ' ,
2020-04-23 08:39:04 +03:00
}
2011-09-09 15:09:44 +04:00
2008-01-21 18:55:53 +03:00
2020-07-17 11:28:39 +03:00
# These are functions which the generator skips completely - no python
2008-01-21 18:55:53 +03:00
# or C code is generated. Generally should not be used for any more
# functions than those already listed
2020-04-23 08:39:04 +03:00
skip_function = {
2018-11-20 10:34:48 +03:00
' virConnectListDomains ' , # Python API is called virConnectListDomainsID 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
2008-10-31 13:13:45 +03:00
' virConnectDomainEventRegister ' , # overridden in virConnect.py
2018-11-20 10:34:48 +03:00
' 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 16:01:48 +03:00
' virConnectDomainEventRegisterAny ' , # overridden in virConnect.py
2018-11-20 10:34:48 +03:00
' virConnectDomainEventDeregisterAny ' , # overridden in virConnect.py
2013-12-11 19:39:09 +04:00
' virConnectNetworkEventRegisterAny ' , # overridden in virConnect.py
2018-11-20 10:34:48 +03:00
' virConnectNetworkEventDeregisterAny ' , # overridden in virConnect.py
2016-06-15 00:22:23 +03:00
' virConnectStoragePoolEventRegisterAny ' , # overridden in virConnect.py
2018-11-20 10:34:48 +03:00
' virConnectStoragePoolEventDeregisterAny ' , # overridden in virConnect.py
2016-07-28 15:14:13 +03:00
' virConnectNodeDeviceEventRegisterAny ' , # overridden in virConnect.py
2018-11-20 10:34:48 +03:00
' virConnectNodeDeviceEventDeregisterAny ' , # overridden in virConnect.py
2017-01-09 21:07:32 +03:00
' virConnectSecretEventRegisterAny ' , # overridden in virConnect.py
2018-11-20 10:34:48 +03:00
' virConnectSecretEventDeregisterAny ' , # overridden in virConnect.py
' virSaveLastError ' , # We have our own python error wrapper
' virFreeError ' , # Only needed if we use virSaveLastError
' virConnectListAllDomains ' , # overridden in virConnect.py
' virDomainListAllCheckpoints ' , # overridden in virDomain.py
' virDomainCheckpointListAllChildren ' , # overridden in virDomainCheckpoint.py
' virDomainListAllSnapshots ' , # overridden in virDomain.py
' virDomainSnapshotListAllChildren ' , # overridden in virDomainSnapshot.py
' virConnectListAllStoragePools ' , # overridden in virConnect.py
' virStoragePoolListAllVolumes ' , # overridden in virStoragePool.py
' virConnectListAllNetworks ' , # overridden in virConnect.py
' virNetworkListAllPorts ' , # overridden in virConnect.py
' virConnectListAllInterfaces ' , # overridden in virConnect.py
' virConnectListAllNodeDevices ' , # overridden in virConnect.py
' virConnectListAllNWFilters ' , # overridden in virConnect.py
' virConnectListAllNWFilterBindings ' , # overridden in virConnect.py
' virConnectListAllSecrets ' , # overridden in virConnect.py
' virConnectGetAllDomainStats ' , # overridden in virConnect.py
' virDomainListGetStats ' , # overridden in virConnect.py
2023-01-12 15:26:37 +03:00
' virDomainFDAssociate ' , # overridden in virDomain.py
2018-11-20 10:34:48 +03:00
' virStreamRecvAll ' , # Pure python libvirt-override-virStream.py
' virStreamSendAll ' , # Pure python libvirt-override-virStream.py
' virStreamRecv ' , # overridden in libvirt-override-virStream.py
' virStreamSend ' , # overridden in libvirt-override-virStream.py
' virStreamRecvHole ' , # overridden in libvirt-override-virStream.py
' virStreamSendHole ' , # overridden in libvirt-override-virStream.py
' virStreamRecvFlags ' , # overridden in libvirt-override-virStream.py
' virStreamSparseRecvAll ' , # overridden in libvirt-override-virStream.py
' virStreamSparseSendAll ' , # overridden in libvirt-override-virStream.py
' virConnectUnregisterCloseCallback ' , # overridden in virConnect.py
' virConnectRegisterCloseCallback ' , # overridden in virConnect.py
' virDomainCreateXMLWithFiles ' , # overridden in virConnect.py
' virDomainCreateWithFiles ' , # overridden in virDomain.py
' virDomainFSFreeze ' , # overridden in virDomain.py
' virDomainFSThaw ' , # overridden in virDomain.py
' virDomainGetTime ' , # overridden in virDomain.py
' virDomainSetTime ' , # overridden in virDomain.py
2014-05-10 03:21:08 +04:00
2011-06-14 21:49:22 +04:00
# 'Ref' functions have no use for bindings users.
2009-09-23 20:17:03 +04:00
" virConnectRef " ,
" virDomainRef " ,
" virInterfaceRef " ,
" virNetworkRef " ,
2019-06-18 14:08:32 +03:00
" virNetworkPortRef " ,
2009-09-23 20:17:03 +04:00
" virNodeDeviceRef " ,
" virSecretRef " ,
2010-04-29 14:46:01 +04:00
" virNWFilterRef " ,
2018-06-26 13:18:32 +03:00
" virNWFilterBindingRef " ,
2009-09-23 20:17:03 +04:00
" virStoragePoolRef " ,
" virStorageVolRef " ,
2013-11-26 20:54:49 +04:00
" virStreamRef " ,
2019-02-08 01:36:16 +03:00
" virDomainCheckpointRef " ,
2013-11-26 20:54:49 +04:00
" virDomainSnapshotRef " ,
2009-09-23 20:38:47 +04: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 " ,
2019-06-18 14:08:32 +03:00
" virNetworkPortGetNetwork " ,
2009-09-23 20:38:47 +04:00
" virSecretGetConnect " ,
2010-04-29 14:46:01 +04:00
" virNWFilterGetConnect " ,
2009-09-23 20:38:47 +04:00
" virStoragePoolGetConnect " ,
" virStorageVolGetConnect " ,
2019-02-08 01:36:16 +03:00
" virDomainCheckpointGetConnect " ,
" virDomainCheckpointGetDomain " ,
2013-01-23 15:14:57 +04:00
" virDomainSnapshotGetConnect " ,
" virDomainSnapshotGetDomain " ,
2013-01-15 17:51:45 +04:00
# only useful in C code, python code uses dict for typed parameters
" virTypedParamsAddBoolean " ,
" virTypedParamsAddDouble " ,
" virTypedParamsAddFromString " ,
" virTypedParamsAddInt " ,
" virTypedParamsAddLLong " ,
" virTypedParamsAddString " ,
" virTypedParamsAddUInt " ,
" virTypedParamsAddULLong " ,
2013-01-16 03:42:35 +04:00
" virTypedParamsClear " ,
2013-01-15 17:51:45 +04:00
" virTypedParamsFree " ,
" virTypedParamsGet " ,
" virTypedParamsGetBoolean " ,
" virTypedParamsGetDouble " ,
" virTypedParamsGetInt " ,
" virTypedParamsGetLLong " ,
" virTypedParamsGetString " ,
" virTypedParamsGetUInt " ,
" virTypedParamsGetULLong " ,
Implement new virNetworkGetDHCPLeases API
This API returns a list of DHCP leases for all network interfaces
connected to the given virtual network or limited output just for one
interface if mac is specified.
Example Output:
[{'iface': 'virbr3', 'ipaddr': '192.168.150.181', 'hostname': 'ubuntu14',
'expirytime': 1403737495L, 'prefix': 24, 'clientid': None,
'mac': '52:54:00:e8:73:eb', 'iaid': None, 'type': 0},
{'iface': 'virbr3', 'ipaddr': '2001:db8:ca2:2:1::bd', 'hostname': 'fedora20-test',
'expirytime': 1403738587L, 'prefix': 64, 'clientid': '00:04:b1:d8:86:42:e1:6a:aa:cf:d5:86:94:23:6f:94:04:cd',
'mac': '52:54:00:5b:40:98', 'iaid': '5980312', 'type': 1}]
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
2014-06-26 02:45:30 +04:00
2018-11-20 10:34:48 +03:00
' virNetworkDHCPLeaseFree ' , # only useful in C, python code uses list
' virDomainStatsRecordListFree ' , # only useful in C, python uses dict
' virDomainFSInfoFree ' , # only useful in C, python code uses list
' virDomainIOThreadInfoFree ' , # only useful in C, python code uses list
' virDomainInterfaceFree ' , # only useful in C, python code uses list
2008-01-21 18:55:53 +03:00
2018-11-20 10:34:48 +03:00
" virDomainLxcEnterNamespace " ,
" virDomainLxcEnterSecurityLabel " ,
2022-03-24 15:23:46 +03:00
2018-11-20 10:34:48 +03:00
# "virDomainQemuAttach",
' virConnectDomainQemuMonitorEventRegister ' , # overridden in -qemu.py
' virConnectDomainQemuMonitorEventDeregister ' , # overridden in -qemu.py
2022-03-04 12:09:46 +03:00
' virDomainQemuMonitorCommandWithFiles ' , # overridden in -qemu.py
2020-04-23 08:39:04 +03:00
}
2011-09-09 15:09:44 +04:00
2011-06-21 04:06:49 +04:00
# Generate C code, but skip python impl
2020-04-23 08:39:04 +03:00
function_skip_python_impl = {
2018-11-20 10:34:48 +03:00
" virStreamFree " , # Needed in custom virStream __del__, but free shouldn't
# be exposed in bindings
2020-04-23 08:39:04 +03:00
}
2011-06-21 04:06:49 +04:00
2020-04-23 08:39:04 +03:00
function_skip_index_one = {
2010-05-19 17:02:30 +04:00
" virDomainRevertToSnapshot " ,
2020-04-23 08:39:04 +03:00
}
2010-05-19 17:02:30 +04:00
2018-11-20 10:34:48 +03:00
2022-03-24 20:40:31 +03:00
def validate_function ( name ) :
( desc , ret , args , file , mod , cond ) = functions [ name ]
if name in skip_function :
return [ ]
if name in skip_impl :
return [ ]
failed = False
unknown = [ ]
for a_name , a_type , a_info in args :
# This should be correct
if a_type [ 0 : 6 ] == " const " :
a_type = a_type [ 6 : ]
if a_type in skipped_types :
return [ ]
if a_type not in py_types :
unknown . append ( a_type )
r_type , r_info , r_field = ret
if r_type in skipped_types :
return [ ]
if r_type != ' void ' and r_type not in py_types :
unknown . append ( r_type )
return unknown
def validate_functions ( ) :
unknown_types = defaultdict ( list ) # type: Dict[str, List[str]]
funcs_failed = [ ] # type: List[str]
for name in sorted ( functions ) :
unknown = validate_function ( name )
if unknown :
funcs_failed . append ( name )
for thetype in unknown :
unknown_types [ thetype ] . append ( name )
if unknown_types :
print ( " Missing type converters: " )
for type , count in unknown_types . items ( ) :
print ( " %s : %d " % ( type , len ( count ) ) )
for f in funcs_failed :
print ( " ERROR: failed %s " % f )
if funcs_failed :
return - 1
return 0
2022-03-24 21:04:31 +03:00
def skip_both_impl ( name : str ) - > bool :
if name in skip_function :
return True
( desc , ret , args , file , mod , cond ) = functions [ name ]
for a_name , a_type , a_info in args :
# This should be correct
if a_type [ 0 : 6 ] == " const " :
a_type = a_type [ 6 : ]
if a_type in skipped_types :
return True
r_type , r_info , r_field = ret
if r_type in skipped_types :
return True
return False
def skip_c_impl ( name : str ) - > bool :
if skip_both_impl ( name ) :
return True
if name in skip_impl :
return True
return False
def skip_py_impl ( name : str ) - > bool :
if skip_both_impl ( name ) :
return True
if name in function_skip_python_impl :
return True
return False
def print_function_wrapper ( package : str , name : str , output : IO [ str ] , export : IO [ str ] , include : IO [ str ] ) - > bool :
2020-07-27 11:02:25 +03:00
"""
2022-03-24 21:04:31 +03:00
: returns : True if generated , False if skipped
2020-07-27 11:02:25 +03:00
"""
2022-03-24 15:23:46 +03:00
( desc , ret , args , file , mod , cond ) = functions [ name ]
2005-12-19 19:34:11 +03:00
2022-03-24 21:04:31 +03:00
if skip_c_impl ( name ) :
return False
2005-12-19 19:34:11 +03:00
2013-02-07 11:22:01 +04:00
c_call = " "
2018-11-20 10:34:48 +03:00
format = " "
format_args = " "
c_args = " "
c_return = " "
c_convert = " "
num_bufs = 0
2020-04-20 18:42:55 +03:00
for a_name , a_type , a_info in args :
2005-12-19 19:34:11 +03:00
# This should be correct
2020-04-20 18:42:55 +03:00
if a_type [ 0 : 6 ] == " const " :
a_type = a_type [ 6 : ]
c_args + = " %s %s ; \n " % ( a_type , a_name )
if a_type in py_types :
( f , t , n , c ) = py_types [ a_type ]
2018-11-20 16:04:20 +03:00
if f :
2018-11-20 12:24:24 +03:00
format + = f
2018-11-20 16:04:20 +03:00
if t :
2020-04-20 18:42:55 +03:00
format_args + = " , &pyobj_ %s " % ( a_name )
c_args + = " PyObject *pyobj_ %s ; \n " % ( a_name )
2018-11-20 12:24:24 +03:00
c_convert + = \
2018-11-20 10:34:48 +03:00
" %s = ( %s ) Py %s _Get(pyobj_ %s ); \n " % (
2020-04-20 18:42:55 +03:00
a_name , a_type , t , a_name )
2005-12-19 19:34:11 +03:00
else :
2020-04-20 18:42:55 +03:00
format_args + = " , & %s " % ( a_name )
2011-02-16 18:57:50 +03:00
if f == ' t# ' :
2018-11-20 12:24:24 +03:00
format_args + = " , &py_buffsize %d " % num_bufs
c_args + = " int py_buffsize %d ; \n " % num_bufs
num_bufs + = 1
2018-11-20 17:39:36 +03:00
if c_call :
2018-11-20 12:24:24 +03:00
c_call + = " , "
2020-04-20 18:42:55 +03:00
c_call + = " %s " % ( a_name )
2005-12-19 19:34:11 +03:00
else :
2022-03-24 20:40:31 +03:00
raise Exception ( " Unexpected type %s in function %s " % ( a_type , name ) )
2018-11-20 17:39:36 +03:00
if format :
2018-11-20 12:24:24 +03:00
format + = " : %s " % ( name )
2005-12-19 19:34:11 +03:00
2018-11-20 15:56:15 +03:00
r_type , r_info , r_field = ret
if r_type == ' void ' :
2005-12-19 19:34:11 +03:00
if file == " python_accessor " :
2011-02-16 18:57:50 +03:00
if args [ 1 ] [ 1 ] == " char * " :
2012-02-03 02:45:54 +04:00
c_call = " \n VIR_FREE( %s -> %s ); \n " % (
2018-11-20 10:34:48 +03:00
args [ 0 ] [ 0 ] , args [ 1 ] [ 0 ] )
2018-11-20 12:24:24 +03:00
c_call + = " %s -> %s = ( %s )strdup((const xmlChar *) %s ); \n " % (
2018-11-20 10:34:48 +03:00
args [ 0 ] [ 0 ] , args [ 1 ] [ 0 ] , args [ 1 ] [ 1 ] , args [ 1 ] [ 0 ] )
2011-02-16 18:57:50 +03:00
else :
c_call = " \n %s -> %s = %s ; \n " % ( args [ 0 ] [ 0 ] , args [ 1 ] [ 0 ] ,
args [ 1 ] [ 0 ] )
2005-12-19 19:34:11 +03:00
else :
2013-02-07 11:22:01 +04:00
c_call = " \n %s ( %s ); \n " % ( name , c_call )
2012-03-22 15:33:35 +04:00
ret_convert = " Py_INCREF(Py_None); \n return Py_None; \n "
2020-04-20 18:42:55 +03:00
elif r_type in py_types :
( f , t , n , c ) = py_types [ r_type ]
c_return = " %s c_retval; \n " % ( r_type )
if file == " python_accessor " and r_field :
c_call = " \n c_retval = %s -> %s ; \n " % ( args [ 0 ] [ 0 ] , r_field )
2005-12-19 19:34:11 +03:00
else :
2013-02-07 11:22:01 +04:00
c_call = " \n c_retval = %s ( %s ); \n " % ( name , c_call )
2018-11-20 10:34:48 +03:00
ret_convert = " py_retval = libvirt_ %s Wrap(( %s ) c_retval); \n " % ( n , c )
2014-09-12 12:49:02 +04:00
if n == " charPtr " :
2018-11-20 12:24:24 +03:00
ret_convert + = " free(c_retval); \n "
ret_convert + = " return py_retval; \n "
2005-12-19 19:34:11 +03:00
else :
2022-03-24 20:40:31 +03:00
raise Exception ( " Unexpected type %s in function %s " % ( r_type , name ) )
2005-12-19 19:34:11 +03:00
2018-11-20 16:04:20 +03:00
if cond :
2005-12-19 19:34:11 +03:00
include . write ( " #if %s \n " % cond )
export . write ( " #if %s \n " % cond )
output . write ( " #if %s \n " % cond )
include . write ( " PyObject * " )
2022-03-24 19:04:21 +03:00
include . write ( " %s _ %s (PyObject *self, PyObject *args); \n " % ( package , name ) )
export . write ( " { (char *) \" %s \" , %s _ %s , METH_VARARGS, NULL }, \n " %
( name , package , name ) )
2005-12-19 19:34:11 +03:00
if file == " python " :
# Those have been manually generated
2018-11-20 16:04:20 +03:00
if cond :
2013-02-07 11:22:01 +04:00
include . write ( " #endif \n " )
export . write ( " #endif \n " )
output . write ( " #endif \n " )
2022-03-24 21:04:31 +03:00
return True
2020-04-20 18:42:55 +03:00
if file == " python_accessor " and r_type != " void " and not r_field :
2005-12-19 19:34:11 +03:00
# Those have been manually generated
2018-11-20 16:04:20 +03:00
if cond :
2013-02-07 11:22:01 +04:00
include . write ( " #endif \n " )
export . write ( " #endif \n " )
output . write ( " #endif \n " )
2022-03-24 21:04:31 +03:00
return True
2005-12-19 19:34:11 +03:00
output . write ( " PyObject * \n " )
2022-03-24 19:04:21 +03:00
output . write ( " %s _ %s (PyObject *self ATTRIBUTE_UNUSED, " % ( package , name ) )
2005-12-19 19:34:11 +03:00
output . write ( " PyObject *args " )
if format == " " :
2011-02-16 18:57:50 +03:00
output . write ( " ATTRIBUTE_UNUSED " )
2005-12-19 19:34:11 +03:00
output . write ( " ) { \n " )
2020-04-20 18:42:55 +03:00
if r_type != ' void ' :
2005-12-19 19:34:11 +03:00
output . write ( " PyObject *py_retval; \n " )
2018-11-20 17:39:36 +03:00
if c_return :
2005-12-19 19:34:11 +03:00
output . write ( c_return )
2018-11-20 17:39:36 +03:00
if c_args :
2005-12-19 19:34:11 +03:00
output . write ( c_args )
2018-11-20 17:39:36 +03:00
if format :
2005-12-19 19:34:11 +03:00
output . write ( " \n if (!PyArg_ParseTuple(args, (char *) \" %s \" %s )) \n " %
( format , format_args ) )
2012-03-22 15:33:35 +04:00
output . write ( " return NULL; \n " )
2018-11-20 17:39:36 +03:00
if c_convert :
2011-09-09 15:09:44 +04:00
output . write ( c_convert + " \n " )
2006-10-25 00:28:16 +04:00
2013-02-07 11:22:01 +04:00
output . write ( " LIBVIRT_BEGIN_ALLOW_THREADS; " )
output . write ( c_call )
output . write ( " LIBVIRT_END_ALLOW_THREADS; \n " )
2005-12-19 19:34:11 +03:00
output . write ( ret_convert )
output . write ( " } \n \n " )
2018-11-20 16:04:20 +03:00
if cond :
2005-12-19 19:34:11 +03:00
include . write ( " #endif /* %s */ \n " % cond )
export . write ( " #endif /* %s */ \n " % cond )
output . write ( " #endif /* %s */ \n " % cond )
2011-06-21 04:06:49 +04:00
2022-03-24 21:04:31 +03:00
return True
2005-12-19 19:34:11 +03:00
2018-11-20 10:34:48 +03:00
2018-11-20 12:32:36 +03:00
def print_c_pointer ( classname : str , output : IO [ str ] , export : IO [ str ] , include : IO [ str ] ) - > None :
2014-12-11 14:16:12 +03:00
output . write ( " PyObject * \n " )
output . write ( " libvirt_ %s _pointer(PyObject *self ATTRIBUTE_UNUSED, PyObject *args) \n " % classname )
output . write ( " { \n " )
output . write ( " %s Ptr ptr; \n " % classname )
output . write ( " PyObject *pyptr; \n " )
output . write ( " PyObject *pylong; \n " )
output . write ( " \n " )
output . write ( " if (!PyArg_ParseTuple(args, (char *) \" O \" , &pyptr)) \n " )
output . write ( " return NULL; \n " )
output . write ( " ptr = ( %s Ptr) Py %s _Get(pyptr); \n " % ( classname , classname ) )
output . write ( " pylong = PyLong_FromVoidPtr(ptr); \n " )
output . write ( " return pylong; \n " )
output . write ( " } \n " )
output . write ( " \n " )
include . write ( " PyObject *libvirt_ %s _pointer(PyObject *self, PyObject *args); \n " % classname )
export . write ( " { (char *) \" %s _pointer \" , libvirt_ %s _pointer, METH_VARARGS, NULL }, \n " %
( classname , classname ) )
2018-11-20 10:34:48 +03:00
2022-03-24 19:58:15 +03:00
def load_apis ( module : str , api_xml : str ) :
2013-11-27 02:37:05 +04:00
global onlyOverrides
2005-12-19 19:34:11 +03:00
try :
2013-11-22 18:09:55 +04:00
onlyOverrides = False
2018-11-20 15:20:53 +03:00
with open ( api_xml ) as stream :
parse ( stream )
2018-11-20 10:59:35 +03:00
except IOError as msg :
2020-04-20 13:18:10 +03:00
print ( api_xml , " : " , msg )
2013-11-12 22:21:45 +04:00
sys . exit ( 1 )
2005-12-19 19:34:11 +03:00
2022-03-24 19:04:21 +03:00
n = len ( functions )
2011-05-12 14:19:42 +04:00
if not quiet :
2013-12-03 14:50:30 +04:00
print ( " Found %d functions in %s " % ( ( n ) , api_xml ) )
2005-12-19 19:34:11 +03:00
2011-09-09 15:09:44 +04:00
override_api_xml = " %s -override-api.xml " % module
2005-12-19 19:34:11 +03:00
py_types [ ' pythonObject ' ] = ( ' O ' , " pythonObject " , " pythonObject " , " pythonObject " )
2011-09-09 15:09:44 +04:00
2005-12-19 19:34:11 +03:00
try :
2013-11-22 18:09:55 +04:00
onlyOverrides = True
2024-04-26 17:56:43 +03:00
with openSourceFile ( override_api_xml ) as stream :
2018-11-20 15:20:53 +03:00
parse ( stream )
2018-11-20 10:59:35 +03:00
except IOError as msg :
2020-04-20 13:18:10 +03:00
print ( override_api_xml , " : " , msg )
2005-12-19 19:34:11 +03:00
2011-05-12 14:19:42 +04:00
if not quiet :
2011-09-09 15:09:44 +04:00
# XXX: This is not right, same function already in @functions
# will be overwritten.
2022-03-24 19:04:21 +03:00
print ( " Found %d functions in %s " % ( len ( functions ) - n , override_api_xml ) )
2022-03-24 19:58:15 +03:00
2022-03-24 21:12:11 +03:00
def emit_c_code ( module : str ) - > None :
2022-03-24 19:58:15 +03:00
package = module . replace ( ' - ' , ' _ ' )
2005-12-19 19:34:11 +03:00
nb_wrap = 0
2024-04-26 17:56:43 +03:00
header_file = " %s / %s .h " % ( buildDir , module )
2024-04-26 18:43:50 +03:00
export_file = " %s / %s -export.c.inc " % ( buildDir , module )
2024-04-26 17:56:43 +03:00
wrapper_file = " %s / %s .c " % ( buildDir , module )
2011-09-09 15:09:44 +04:00
include = open ( header_file , " w " )
2015-01-15 05:57:42 +03:00
include . write ( " /* Generated by generator.py */ \n \n " )
2011-09-09 15:09:44 +04:00
export = open ( export_file , " w " )
2015-01-15 05:57:42 +03:00
export . write ( " /* Generated by generator.py */ \n \n " )
2011-09-09 15:09:44 +04:00
wrapper = open ( wrapper_file , " w " )
2012-03-21 02:44:39 +04:00
wrapper . write ( " /* Generated by generator.py */ \n \n " )
2023-09-20 20:27:20 +03:00
wrapper . write ( " #include <stdlib.h> \n " )
2005-12-19 19:34:11 +03:00
wrapper . write ( " #include <Python.h> \n " )
2018-11-20 15:33:12 +03:00
wrapper . write ( " #include <libvirt/ %s .h> \n " % ( module , ) )
2009-09-16 17:03:53 +04:00
wrapper . write ( " #include \" typewrappers.h \" \n " )
2024-04-26 18:49:32 +03:00
wrapper . write ( " #include \" %s .h \" \n \n " % ( module ) )
2011-09-09 15:09:44 +04:00
2022-03-24 19:04:21 +03:00
for function in sorted ( functions ) :
2022-03-24 21:04:31 +03:00
if print_function_wrapper ( package , function , wrapper , export , include ) :
2018-11-20 12:23:43 +03:00
nb_wrap + = 1
2014-12-11 14:16:12 +03:00
if module == " libvirt " :
# Write C pointer conversion functions.
for classname in primary_classes :
print_c_pointer ( classname , wrapper , export , include )
2015-01-15 05:57:42 +03:00
# Write define wrappers around event id enums, so that the
# preprocessor can see which enums were available.
for event_id in event_ids :
include . write ( " #define %s %s \n " % ( event_id , event_id ) )
2014-12-11 14:16:12 +03:00
2005-12-19 19:34:11 +03:00
include . close ( )
export . close ( )
wrapper . close ( )
2011-05-12 14:19:42 +04:00
if not quiet :
2013-12-03 14:50:30 +04:00
print ( " Generated %d wrapper functions " % nb_wrap )
2008-01-21 18:55:53 +03:00
2018-11-20 10:34:48 +03:00
2005-12-19 19:34:11 +03: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
2020-04-20 19:28:36 +03:00
# "C-type" -> (accessor, create, class, parent-class)
2005-12-19 19:34:11 +03:00
#
classes_type = {
2020-04-20 19:28:36 +03:00
" virDomainPtr " : ( " ._o " , " virDomain( %(p)s , _obj= %(o)s ) " , " virDomain " , " virConnect " ) ,
" virDomain * " : ( " ._o " , " virDomain( %(p)s , _obj= %(o)s ) " , " virDomain " , " virConnect " ) ,
" virNetworkPtr " : ( " ._o " , " virNetwork( %(p)s , _obj= %(o)s ) " , " virNetwork " , " virConnect " ) ,
" virNetwork * " : ( " ._o " , " virNetwork( %(p)s , _obj= %(o)s ) " , " virNetwork " , " virConnect " ) ,
" virNetworkPortPtr " : ( " ._o " , " virNetworkPort( %(p)s , _obj= %(o)s ) " , " virNetworkPort " , " virNetwork " ) ,
" virNetworkPort * " : ( " ._o " , " virNetworkPort( %(p)s , _obj= %(o)s ) " , " virNetworkPort " , " virNetwork " ) ,
" virInterfacePtr " : ( " ._o " , " virInterface( %(p)s , _obj= %(o)s ) " , " virInterface " , " virConnect " ) ,
" virInterface * " : ( " ._o " , " virInterface( %(p)s , _obj= %(o)s ) " , " virInterface " , " virConnect " ) ,
" virStoragePoolPtr " : ( " ._o " , " virStoragePool( %(p)s , _obj= %(o)s ) " , " virStoragePool " , " virConnect " ) ,
" virStoragePool * " : ( " ._o " , " virStoragePool( %(p)s , _obj= %(o)s ) " , " virStoragePool " , " virConnect " ) ,
" virStorageVolPtr " : ( " ._o " , " virStorageVol( %(p)s , _obj= %(o)s ) " , " virStorageVol " , " virConnect " ) ,
" virStorageVol * " : ( " ._o " , " virStorageVol( %(p)s , _obj= %(o)s ) " , " virStorageVol " , " virConnect " ) ,
" virNodeDevicePtr " : ( " ._o " , " virNodeDevice( %(p)s , _obj= %(o)s ) " , " virNodeDevice " , " virConnect " ) ,
" virNodeDevice * " : ( " ._o " , " virNodeDevice( %(p)s , _obj= %(o)s ) " , " virNodeDevice " , " virConnect " ) ,
" virSecretPtr " : ( " ._o " , " virSecret( %(p)s , _obj= %(o)s ) " , " virSecret " , " virConnect " ) ,
" virSecret * " : ( " ._o " , " virSecret( %(p)s , _obj= %(o)s ) " , " virSecret " , " virConnect " ) ,
" virNWFilterPtr " : ( " ._o " , " virNWFilter( %(p)s , _obj= %(o)s ) " , " virNWFilter " , " virConnect " ) ,
" virNWFilter * " : ( " ._o " , " virNWFilter( %(p)s , _obj= %(o)s ) " , " virNWFilter " , " virConnect " ) ,
" virNWFilterBindingPtr " : ( " ._o " , " virNWFilterBinding( %(p)s , _obj= %(o)s ) " , " virNWFilterBinding " , " virConnect " ) ,
" virNWFilterBinding * " : ( " ._o " , " virNWFilterBinding( %(p)s , _obj= %(o)s ) " , " virNWFilterBinding " , " virConnect " ) ,
" virStreamPtr " : ( " ._o " , " virStream( %(p)s , _obj= %(o)s ) " , " virStream " , " virConnect " ) ,
" virStream * " : ( " ._o " , " virStream( %(p)s , _obj= %(o)s ) " , " virStream " , " virConnect " ) ,
" virConnectPtr " : ( " ._o " , " virConnect(_obj= %(o)s ) " , " virConnect " , " " ) ,
" virConnect * " : ( " ._o " , " virConnect(_obj= %(o)s ) " , " virConnect " , " " ) ,
" virDomainCheckpointPtr " : ( " ._o " , " virDomainCheckpoint( %(p)s , _obj= %(o)s ) " , " virDomainCheckpoint " , " virDomain " ) ,
" virDomainCheckpoint * " : ( " ._o " , " virDomainCheckpoint( %(p)s , _obj= %(o)s ) " , " virDomainCheckpoint " , " virDomain " ) ,
" virDomainSnapshotPtr " : ( " ._o " , " virDomainSnapshot( %(p)s , _obj= %(o)s ) " , " virDomainSnapshot " , " virDomain " ) ,
" virDomainSnapshot * " : ( " ._o " , " virDomainSnapshot( %(p)s , _obj= %(o)s ) " , " virDomainSnapshot " , " virDomain " ) ,
2005-12-19 19:34:11 +03:00
}
2019-06-18 14:08:32 +03:00
primary_classes = [ " virDomain " , " virNetwork " , " virNetworkPort " ,
" virInterface " , " virStoragePool " , " virStorageVol " ,
2009-07-10 15:18:12 +04:00
" virConnect " , " virNodeDevice " , " virSecret " ,
2018-06-26 13:18:32 +03:00
" virNWFilter " , " virNWFilterBinding " ,
2019-02-08 01:36:16 +03:00
" virStream " , " virDomainCheckpoint " , " virDomainSnapshot " ]
2005-12-19 19:34:11 +03:00
classes_destructors = {
" virDomain " : " virDomainFree " ,
2007-03-09 18:42:50 +03:00
" virNetwork " : " virNetworkFree " ,
2019-06-18 14:08:32 +03:00
" virNetworkPort " : " virNetworkPortFree " ,
2009-05-21 14:57:05 +04:00
" virInterface " : " virInterfaceFree " ,
2008-02-20 18:26:22 +03:00
" virStoragePool " : " virStoragePoolFree " ,
" virStorageVol " : " virStorageVolFree " ,
2018-11-20 10:34:48 +03:00
" virNodeDevice " : " virNodeDeviceFree " ,
2009-07-10 15:18:12 +04:00
" virSecret " : " virSecretFree " ,
2010-04-29 14:46:01 +04:00
" virNWFilter " : " virNWFilterFree " ,
2018-06-26 13:18:32 +03:00
" virNWFilterBinding " : " virNWFilterBindingFree " ,
2019-02-08 01:36:16 +03:00
" virDomainCheckpoint " : " virDomainCheckpointFree " ,
2010-04-20 13:49:27 +04:00
" virDomainSnapshot " : " virDomainSnapshotFree " ,
2009-07-10 15:18:12 +04:00
# We hand-craft __del__ for this one
2018-11-20 10:34:48 +03:00
# "virStream": "virStreamFree",
2005-12-19 19:34:11 +03:00
}
2009-09-23 20:38:47 +04:00
class_skip_connect_impl = {
2020-04-23 08:39:04 +03:00
" virConnect " ,
2009-09-23 20:38:47 +04:00
}
2010-05-19 17:02:30 +04:00
class_domain_impl = {
2020-04-23 08:39:04 +03:00
" virDomainCheckpoint " ,
" virDomainSnapshot " ,
2010-05-19 17:02:30 +04:00
}
2009-09-23 20:38:47 +04:00
2019-09-12 15:51:00 +03:00
class_network_impl = {
2020-04-23 08:39:04 +03:00
" virNetworkPort " ,
2019-09-12 15:51:00 +03:00
}
2005-12-19 19:34:11 +03:00
functions_noexcept = {
2020-04-23 08:39:04 +03:00
' virDomainGetID ' ,
' virDomainGetName ' ,
' virNetworkGetName ' ,
' virInterfaceGetName ' ,
' virStoragePoolGetName ' ,
' virStorageVolGetName ' ,
' virStorageVolGetkey ' ,
' virNodeDeviceGetName ' ,
' virNodeDeviceGetParent ' ,
' virSecretGetUsageType ' ,
' virSecretGetUsageID ' ,
' virNWFilterGetName ' ,
' virNWFilterBindingGetFilterName ' ,
' virNWFilterBindingGetPortDev ' ,
2005-12-19 19:34:11 +03:00
}
2018-11-20 13:14:46 +03:00
function_classes = {
" None " : [ ]
2018-11-20 12:32:36 +03:00
} # type: Dict[str, List[Tuple[int, str, str, ArgumentType, List[ArgumentType], str, str]]]
2005-12-19 19:34:11 +03:00
2007-03-28 15:24:14 +04: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 "
2018-11-20 10:34:48 +03:00
2018-11-20 12:32:36 +03:00
def is_integral_type ( name : str ) - > bool :
2018-11-20 12:08:51 +03:00
return re . search ( " ^(unsigned)? ?(int|long)$ " , name ) is not None
2018-11-20 10:34:48 +03:00
2007-03-28 15:24:14 +04:00
2018-11-20 12:32:36 +03:00
def is_optional_arg ( info : str ) - > bool :
2020-07-26 07:12:29 +03:00
return re . search ( r " ^ \ (?optional \ )? " , info ) is not None
2007-03-28 15:24:14 +04:00
2009-07-24 19:05:27 +04:00
2018-11-20 12:32:36 +03:00
def is_python_noninteger_type ( name : str ) - > bool :
2013-03-21 07:24:49 +04:00
return name [ - 1 : ] == " * "
2007-03-28 15:24:14 +04:00
2018-11-20 10:34:48 +03:00
2018-11-20 12:32:36 +03:00
def nameFixup ( name : str , classe : str , type : str , file : str ) - > str :
2019-02-07 23:51:49 +03:00
# avoid a disastrous clash
2005-12-19 19:34:11 +03:00
listname = classe + " List "
l = len ( classe )
if name [ 0 : l ] == listname :
func = name [ l : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2007-03-16 13:44:44 +03:00
elif name [ 0 : 16 ] == " virNetworkDefine " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2009-04-01 14:37:57 +04:00
elif name [ 0 : 19 ] == " virNetworkCreateXML " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2007-03-15 18:23:21 +03:00
elif name [ 0 : 16 ] == " virNetworkLookup " :
2007-03-16 13:44:44 +03:00
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2019-06-18 14:08:32 +03:00
elif name [ 0 : 23 ] == " virNetworkPortCreateXML " :
func = name [ 10 : ]
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
elif name [ 0 : 20 ] == " virNetworkPortLookup " :
func = name [ 10 : ]
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2009-05-21 14:57:05 +04:00
elif name [ 0 : 18 ] == " virInterfaceDefine " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2009-05-21 14:57:05 +04:00
elif name [ 0 : 21 ] == " virInterfaceCreateXML " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2009-05-21 14:57:05 +04:00
elif name [ 0 : 18 ] == " virInterfaceLookup " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + 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-04 22:38:21 +04:00
elif name [ 0 : 15 ] == " virSecretDefine " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + 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-04 22:38:21 +04:00
elif name [ 0 : 15 ] == " virSecretLookup " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2018-06-26 13:18:32 +03:00
elif name [ 0 : 27 ] == " virNWFilterBindingCreateXML " :
func = name [ 3 : ]
2018-06-28 14:29:21 +03:00
func = func [ 0 : 3 ] . lower ( ) + func [ 3 : ]
elif name [ 0 : 24 ] == " virNWFilterBindingLookup " :
func = name [ 3 : ]
func = func [ 0 : 3 ] . lower ( ) + func [ 3 : ]
2018-06-26 13:18:32 +03:00
elif name [ 0 : 24 ] == " virNWFilterBindingDefine " :
func = name [ 3 : ]
func = func [ 0 : 3 ] . lower ( ) + func [ 3 : ]
elif name [ 0 : 24 ] == " virNWFilterBindingLookup " :
func = name [ 3 : ]
func = func [ 0 : 3 ] . lower ( ) + func [ 3 : ]
2010-04-29 14:46:01 +04:00
elif name [ 0 : 17 ] == " virNWFilterDefine " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 3 ] . lower ( ) + func [ 3 : ]
2010-04-29 14:46:01 +04:00
elif name [ 0 : 17 ] == " virNWFilterLookup " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 3 ] . lower ( ) + func [ 3 : ]
2008-02-20 18:26:22 +03:00
elif name [ 0 : 20 ] == " virStoragePoolDefine " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2009-04-01 14:37:57 +04:00
elif name [ 0 : 23 ] == " virStoragePoolCreateXML " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2008-02-20 18:26:22 +03:00
elif name [ 0 : 20 ] == " virStoragePoolLookup " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2008-02-20 18:26:22 +03:00
elif name [ 0 : 19 ] == " virStorageVolDefine " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2008-02-20 18:26:22 +03:00
elif name [ 0 : 19 ] == " virStorageVolLookup " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2012-03-20 08:34:06 +04:00
elif name [ 0 : 20 ] == " virDomainGetCPUStats " :
func = name [ 9 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2015-03-26 14:22:13 +03:00
elif name [ 0 : 24 ] == " virDomainGetIOThreadInfo " :
Support virDomainGetIOThreadsInfo and virDomainIOThreadsInfoFree
Add support for the libvirt_virDomainGetIOThreadsInfo method. This
code mostly follows the libvirt_virDomainGetVcpuPinInfo method, but
also takes some from the libvirt_virNodeGetCPUMap method with respect
to building the cpumap into the returned tuple rather than two separate
tuples which vcpu pinning generates
Assuming two domains, one with IOThreads defined (eg, 'iothr-gst') and
one without ('noiothr-gst'), execute the following in an 'iothr.py' file:
import libvirt
con=libvirt.open("qemu:///system")
dom=con.lookupByName('iothr-gst')
print dom.ioThreadsInfo()
dom2=con.lookupByName('noiothr-gst')
print dom2.ioThreadsInfo()
$ python iothr.py
[(1, [False, False, True, False]), (2, [False, False, False, True]), (3, [True, True, True, True])]
[]
$
2015-02-19 04:22:06 +03:00
func = name [ 12 : ]
func = func [ 0 : 2 ] . lower ( ) + func [ 2 : ]
2014-11-22 04:28:00 +03:00
elif name [ 0 : 18 ] == " virDomainGetFSInfo " :
func = name [ 12 : ]
func = func [ 0 : 2 ] . lower ( ) + func [ 2 : ]
2005-12-19 19:34:11 +03:00
elif name [ 0 : 12 ] == " virDomainGet " :
func = name [ 12 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2019-02-08 01:36:16 +03:00
elif name [ 0 : 31 ] == " virDomainCheckpointLookupByName " :
func = name [ 9 : ]
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
elif name [ 0 : 28 ] == " virDomainCheckpointCreateXML " :
func = name [ 9 : ]
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
elif name [ 0 : 19 ] == " virDomainCheckpoint " :
func = name [ 19 : ]
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2010-04-20 13:49:27 +04:00
elif name [ 0 : 29 ] == " virDomainSnapshotLookupByName " :
func = name [ 9 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2010-04-20 13:49:27 +04:00
elif name [ 0 : 26 ] == " virDomainSnapshotListNames " :
func = name [ 9 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2011-09-25 05:56:26 +04:00
elif name [ 0 : 28 ] == " virDomainSnapshotNumChildren " :
func = name [ 17 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2010-04-20 13:49:27 +04:00
elif name [ 0 : 20 ] == " virDomainSnapshotNum " :
func = name [ 9 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2010-04-20 13:49:27 +04:00
elif name [ 0 : 26 ] == " virDomainSnapshotCreateXML " :
func = name [ 9 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2010-04-20 13:49:27 +04:00
elif name [ 0 : 24 ] == " virDomainSnapshotCurrent " :
func = name [ 9 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2010-04-20 13:49:27 +04:00
elif name [ 0 : 17 ] == " virDomainSnapshot " :
func = name [ 17 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2005-12-19 19:34:11 +03:00
elif name [ 0 : 9 ] == " virDomain " :
func = name [ 9 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2019-06-20 16:10:08 +03:00
elif name [ 0 : 17 ] == " virNetworkPortGet " :
func = name [ 17 : ]
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2007-03-09 18:42:50 +03:00
elif name [ 0 : 13 ] == " virNetworkGet " :
func = name [ 13 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
Implement new virNetworkGetDHCPLeases API
This API returns a list of DHCP leases for all network interfaces
connected to the given virtual network or limited output just for one
interface if mac is specified.
Example Output:
[{'iface': 'virbr3', 'ipaddr': '192.168.150.181', 'hostname': 'ubuntu14',
'expirytime': 1403737495L, 'prefix': 24, 'clientid': None,
'mac': '52:54:00:e8:73:eb', 'iaid': None, 'type': 0},
{'iface': 'virbr3', 'ipaddr': '2001:db8:ca2:2:1::bd', 'hostname': 'fedora20-test',
'expirytime': 1403738587L, 'prefix': 64, 'clientid': '00:04:b1:d8:86:42:e1:6a:aa:cf:d5:86:94:23:6f:94:04:cd',
'mac': '52:54:00:5b:40:98', 'iaid': '5980312', 'type': 1}]
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
2014-06-26 02:45:30 +04:00
func = func . replace ( " dHCP " , " DHCP " )
2019-06-18 14:08:32 +03:00
elif name [ 0 : 14 ] == " virNetworkPort " :
func = name [ 14 : ]
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2007-03-09 18:42:50 +03:00
elif name [ 0 : 10 ] == " virNetwork " :
func = name [ 10 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2009-05-21 14:57:05 +04:00
elif name [ 0 : 15 ] == " virInterfaceGet " :
2009-09-23 20:51:55 +04:00
func = name [ 15 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2009-05-21 14:57:05 +04:00
elif name [ 0 : 12 ] == " virInterface " :
2009-09-23 20:51:55 +04:00
func = name [ 12 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + 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-04 22:38:21 +04:00
elif name [ 0 : 12 ] == ' virSecretGet ' :
func = name [ 12 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + 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-04 22:38:21 +04:00
elif name [ 0 : 9 ] == ' virSecret ' :
func = name [ 9 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2018-06-26 13:18:32 +03:00
elif name [ 0 : 21 ] == ' virNWFilterBindingGet ' :
func = name [ 21 : ]
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
elif name [ 0 : 18 ] == ' virNWFilterBinding ' :
func = name [ 18 : ]
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2010-04-29 14:46:01 +04:00
elif name [ 0 : 14 ] == ' virNWFilterGet ' :
func = name [ 14 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2010-04-29 14:46:01 +04:00
elif name [ 0 : 11 ] == ' virNWFilter ' :
func = name [ 11 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2009-07-10 15:18:12 +04:00
elif name [ 0 : 12 ] == ' virStreamNew ' :
func = " newStream "
elif name [ 0 : 9 ] == ' virStream ' :
func = name [ 9 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2008-02-20 18:26:22 +03:00
elif name [ 0 : 17 ] == " virStoragePoolGet " :
func = name [ 17 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2008-02-20 18:26:22 +03:00
elif name [ 0 : 14 ] == " virStoragePool " :
func = name [ 14 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2008-02-20 18:26:22 +03:00
elif name [ 0 : 16 ] == " virStorageVolGet " :
func = name [ 16 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2008-02-20 18:26:22 +03:00
elif name [ 0 : 13 ] == " virStorageVol " :
func = name [ 13 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2021-04-14 22:22:23 +03:00
elif name [ 0 : 16 ] == " virNodeDeviceGet " :
func = name [ 16 ] . lower ( ) + name [ 17 : ]
elif name [ 0 : 19 ] == " virNodeDeviceLookup " :
func = name [ 3 ] . lower ( ) + name [ 4 : ]
elif name [ 0 : 22 ] == " virNodeDeviceCreateXML " :
func = name [ 3 ] . lower ( ) + name [ 4 : ]
elif name [ 0 : 19 ] == " virNodeDeviceDefine " :
func = name [ 3 ] . lower ( ) + name [ 4 : ]
2008-11-21 15:41:15 +03:00
elif name [ 0 : 13 ] == " virNodeDevice " :
2021-04-14 22:22:23 +03:00
func = name [ 13 ] . lower ( ) + name [ 14 : ]
2006-03-29 16:46:03 +04:00
elif name [ 0 : 7 ] == " virNode " :
func = name [ 7 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2005-12-19 19:34:11 +03:00
elif name [ 0 : 10 ] == " virConnect " :
func = name [ 10 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2005-12-19 19:34:11 +03:00
elif name [ 0 : 3 ] == " xml " :
func = name [ 3 : ]
2013-12-03 14:45:41 +04:00
func = func [ 0 : 1 ] . lower ( ) + func [ 1 : ]
2005-12-19 19:34:11 +03:00
else :
func = name
2006-01-31 13:24:12 +03:00
if func == " iD " :
func = " ID "
2006-02-23 14:26:17 +03:00
if func == " uUID " :
func = " UUID "
2007-03-09 18:42:50 +03:00
if func == " uUIDString " :
func = " UUIDString "
2006-01-31 13:24:12 +03:00
if func == " oSType " :
func = " OSType "
if func == " xMLDesc " :
func = " XMLDesc "
2009-09-23 20:51:55 +04:00
if func == " mACString " :
func = " MACString "
2005-12-19 19:34:11 +03:00
return func
2018-11-20 12:32:36 +03:00
def functionSortKey ( info : Tuple ) - > Tuple [ str , str ] :
2013-12-03 16:07:02 +04:00
( index , func , name , ret , args , filename , mod ) = info
return func , filename
2005-12-19 19:34:11 +03:00
2018-11-20 10:34:48 +03:00
2018-11-20 12:32:36 +03:00
def writeDoc ( module : str , name : str , args : List [ ArgumentType ] , indent : str , output : IO ) - > None :
2022-03-24 19:04:21 +03:00
if not functions [ name ] [ 0 ] :
2018-11-20 10:34:48 +03:00
return
2022-03-24 19:04:21 +03:00
val = functions [ name ] [ 0 ]
2018-11-20 10:34:48 +03:00
val = val . replace ( " NULL " , " None " )
2018-11-20 13:42:58 +03:00
sep = ' \n %s ' % ( indent , )
output . write ( ' %s " " " %s " " " \n ' % ( indent , sep . join ( val . splitlines ( ) ) ) )
2018-11-20 10:34:48 +03:00
2005-12-19 19:34:11 +03:00
2022-03-24 21:12:11 +03:00
def emit_py_code ( module : str ) - > None :
2022-03-24 19:16:33 +03:00
package = module . replace ( ' - ' , ' _ ' )
if module == " libvirt " :
pymod = " libvirtmod "
cygmod = " cygvirtmod "
elif module == " libvirt-lxc " :
pymod = " libvirtmod_lxc "
cygmod = " cygvirtmod_lxc "
elif module == " libvirt-qemu " :
pymod = " libvirtmod_qemu "
cygmod = " cygvirtmod_qemu "
else :
raise Exception ( " Unknown module ' %s ' " % module )
2018-11-20 13:31:32 +03:00
for tinfo in classes_type . values ( ) :
function_classes [ tinfo [ 2 ] ] = [ ]
2005-12-19 19:34:11 +03:00
#
# Build the list of C types to look for ordered to start
# with primary classes
#
2018-11-20 12:32:36 +03:00
ctypes = [ ] # type: List[str]
classes_list = [ ] # type: List[str]
ctypes_processed = set ( ) # type: Set[str]
classes_processed = set ( ) # type: Set[str]
2005-12-19 19:34:11 +03:00
for classe in primary_classes :
2011-02-16 18:57:50 +03:00
classes_list . append ( classe )
2020-04-23 08:39:04 +03:00
classes_processed . add ( classe )
2018-11-20 13:30:48 +03:00
for type , tinfo in classes_type . items ( ) :
2011-02-16 18:57:50 +03:00
if tinfo [ 2 ] == classe :
ctypes . append ( type )
2020-04-23 08:39:04 +03:00
ctypes_processed . add ( type )
2018-11-20 13:30:48 +03:00
for type , tinfo in classes_type . items ( ) :
2013-12-03 15:01:44 +04:00
if type in ctypes_processed :
2011-02-16 18:57:50 +03:00
continue
2013-12-03 15:01:44 +04:00
if tinfo [ 2 ] not in classes_processed :
2011-02-16 18:57:50 +03:00
classes_list . append ( tinfo [ 2 ] )
2020-04-23 08:39:04 +03:00
classes_processed . add ( tinfo [ 2 ] )
2008-02-05 22:27:37 +03:00
2011-02-16 18:57:50 +03:00
ctypes . append ( type )
2020-04-23 08:39:04 +03:00
ctypes_processed . add ( type )
2005-12-19 19:34:11 +03:00
2018-11-20 13:30:48 +03:00
for name , ( desc , ret , args , file , mod , cond ) in functions . items ( ) :
2022-03-24 21:04:31 +03:00
if skip_py_impl ( name ) :
continue
2011-02-16 18:57:50 +03:00
for type in ctypes :
classe = classes_type [ type ] [ 2 ]
if name [ 0 : 3 ] == " vir " and len ( args ) > = 1 and args [ 0 ] [ 1 ] == type :
func = nameFixup ( name , classe , type , file )
2011-09-09 15:09:44 +04:00
info = ( 0 , func , name , ret , args , file , mod )
2011-02-16 18:57:50 +03:00
function_classes [ classe ] . append ( info )
2013-11-26 20:57:51 +04:00
break
2011-02-16 18:57:50 +03:00
elif name [ 0 : 3 ] == " vir " and len ( args ) > = 2 and args [ 1 ] [ 1 ] == type \
2018-11-20 12:08:51 +03:00
and file != " python_accessor " and name not in function_skip_index_one :
2011-02-16 18:57:50 +03:00
func = nameFixup ( name , classe , type , file )
2011-09-09 15:09:44 +04:00
info = ( 1 , func , name , ret , args , file , mod )
2011-02-16 18:57:50 +03:00
function_classes [ classe ] . append ( info )
2013-11-26 20:57:51 +04:00
break
2018-11-20 17:22:23 +03:00
else :
func = nameFixup ( name , " None " , file , file )
info = ( 0 , func , name , ret , args , file , mod )
function_classes [ ' None ' ] . append ( info )
2008-02-05 22:27:37 +03:00
2024-04-26 17:56:43 +03:00
classes_file = " %s / %s .py " % ( buildDir , package )
2013-11-12 22:21:45 +04:00
extra_file = " %s -override.py " % module
2024-04-26 17:56:43 +03:00
extra = openSourceFile ( extra_file , " r " , True )
2011-09-09 15:09:44 +04:00
classes = open ( classes_file , " w " )
2009-09-16 17:03:53 +04: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 " )
2018-11-20 15:33:12 +03:00
classes . write ( " # To change the manually written methods edit %s -override.py \n " % ( module , ) )
2009-09-16 17:03:53 +04:00
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 " )
2022-03-24 19:16:33 +03:00
classes . write ( " try: \n " )
classes . write ( " import %s # type: ignore \n " % pymod )
classes . write ( " except ImportError as lib_e: \n " )
classes . write ( " try: \n " )
classes . write ( " import %s as %s # type: ignore \n " % ( cygmod , pymod ) )
classes . write ( " except ImportError as cyg_e: \n " )
classes . write ( " if \" No module named \" in str(cyg_e): \n " )
classes . write ( " raise lib_e \n \n " )
2022-03-24 19:35:13 +03:00
if module != " libvirt " :
classes . write ( " import libvirt \n " )
classes . write ( " \n " )
2018-11-20 17:39:36 +03:00
if extra :
2022-03-24 19:16:33 +03:00
classes . write ( " # WARNING WARNING WARNING WARNING \n " )
classes . write ( " # \n " )
2022-03-24 19:35:13 +03:00
classes . write ( " # Manually written part of python bindings for %s \n " % module )
2011-09-09 15:09:44 +04:00
classes . writelines ( extra . readlines ( ) )
2009-09-16 17:03:53 +04:00
classes . write ( " # \n " )
classes . write ( " # WARNING WARNING WARNING WARNING \n " )
classes . write ( " # \n " )
2022-03-24 19:35:13 +03:00
classes . write ( " # Automatically written part of python bindings for %s \n " % module )
2009-09-16 17:03:53 +04:00
classes . write ( " # \n " )
classes . write ( " # WARNING WARNING WARNING WARNING \n " )
2018-11-20 17:39:36 +03:00
if extra :
2011-09-09 15:09:44 +04:00
extra . close ( )
2005-12-19 19:34:11 +03:00
2013-12-03 15:01:44 +04:00
if " None " in function_classes :
2011-02-16 18:57:50 +03:00
flist = function_classes [ " None " ]
oldfile = " "
2020-04-20 18:42:55 +03:00
for ( index , func , name , ret , args , file , mod ) in sorted ( flist , key = functionSortKey ) :
2011-02-16 18:57:50 +03:00
if file != oldfile :
classes . write ( " # \n # Functions from module %s \n # \n \n " % file )
oldfile = file
classes . write ( " def %s ( " % func )
2018-11-20 15:56:15 +03:00
for n , ( a_name , a_type , a_info ) in enumerate ( args ) :
2011-02-16 18:57:50 +03:00
if n != 0 :
classes . write ( " , " )
2018-11-20 15:56:15 +03:00
classes . write ( " %s " % a_name )
if a_name == " flags " or is_optional_arg ( a_info ) :
if is_integral_type ( a_type ) :
python: set default value to optional arguments
When prefixing with string (optional) or optional in the description
of arguments to libvirt C APIs, in python, these arguments will be
set as optional arugments, for example:
* virDomainSaveFlags:
* @domain: a domain object
* @to: path for the output file
* @dxml: (optional) XML config for adjusting guest xml used on restore
* @flags: bitwise-OR of virDomainSaveRestoreFlags
the corresponding python APIs is
restoreFlags(self, frm, dxml=None, flags=0)
The following python APIs are changed to:
blockCommit(self, disk, base, top, bandwidth=0, flags=0)
blockPull(self, disk, bandwidth=0, flags=0)
blockRebase(self, disk, base, bandwidth=0, flags=0)
migrate(self, dconn, flags=0, dname=None, uri=None, bandwidth=0)
migrate2(self, dconn, dxml=None, flags=0, dname=None, uri=None, bandwidth=0)
migrateToURI(self, duri, flags=0, dname=None, bandwidth=0)
migrateToURI2(self, dconnuri=None, miguri=None, dxml=None, flags=0, \
dname=None, bandwidth=0)
saveFlags(self, to, dxml=None, flags=0)
migrate(self, domain, flags=0, dname=None, uri=None, bandwidth=0)
migrate2(self, domain, dxml=None, flags=0, dname=None, uri=None, bandwidth=0)
restoreFlags(self, frm, dxml=None, flags=0)
2013-03-26 08:34:49 +04:00
classes . write ( " =0 " )
else :
classes . write ( " =None " )
2011-02-16 18:57:50 +03:00
classes . write ( " ): \n " )
2013-02-07 11:22:01 +04:00
writeDoc ( module , name , args , ' ' , classes )
2011-02-16 18:57:50 +03:00
2018-11-20 15:56:15 +03:00
for a_name , a_type , a_info in args :
if a_type in classes_type :
2020-04-23 08:46:21 +03:00
classes . write ( " if %s is None: \n "
" %s __o = None \n " %
2018-11-20 15:56:15 +03:00
( a_name , a_name ) )
2020-04-23 08:46:21 +03:00
classes . write ( " else: \n "
" %s __o = %s %s \n " %
2018-11-20 15:56:15 +03:00
( a_name , a_name , classes_type [ a_type ] [ 0 ] ) )
r_type , r_info , r_field = ret
if r_type != " void " :
2013-02-07 11:22:01 +04:00
classes . write ( " ret = " )
2011-02-16 18:57:50 +03:00
else :
2013-02-07 11:22:01 +04:00
classes . write ( " " )
2022-03-24 19:16:33 +03:00
classes . write ( " %s . %s ( " % ( pymod , name ) )
2018-11-20 15:56:15 +03:00
for n , ( a_name , a_type , a_info ) in enumerate ( args ) :
2011-02-16 18:57:50 +03:00
if n != 0 :
2013-02-07 11:22:01 +04:00
classes . write ( " , " )
2018-11-20 15:56:15 +03:00
classes . write ( " %s " % a_name )
if a_type in classes_type :
2013-02-07 11:22:01 +04:00
classes . write ( " __o " )
classes . write ( " ) \n " )
2007-03-28 15:24:14 +04:00
2018-11-20 15:56:15 +03:00
if r_type != " void " :
if r_type in classes_type :
2011-02-16 18:57:50 +03:00
#
# Raise an exception
#
2013-12-03 15:01:44 +04:00
if name in functions_noexcept :
2020-04-23 08:46:21 +03:00
classes . write ( " if ret is None: \n "
" return None \n " )
2011-02-16 18:57:50 +03:00
else :
classes . write (
2020-04-23 08:46:21 +03:00
" if ret is None: \n "
" raise libvirtError( ' %s () failed ' ) \n " %
2018-11-20 10:34:48 +03:00
( name ) )
2011-02-16 18:57:50 +03:00
2020-04-20 19:28:36 +03:00
tinfo = classes_type [ r_type ]
2013-02-07 11:22:01 +04:00
classes . write ( " return " )
2020-04-20 19:28:36 +03:00
classes . write ( tinfo [ 1 ] % { " o " : " ret " } )
2013-02-07 11:22:01 +04:00
classes . write ( " \n " )
2007-03-28 15:24:14 +04:00
# For functions returning an integral type there are
# several things that we can do, depending on the
# contents of functions_int_*:
2018-11-20 15:56:15 +03:00
elif is_integral_type ( r_type ) :
2013-12-03 15:01:44 +04:00
if name not in functions_noexcept :
2020-04-19 16:55:12 +03:00
test = functions_int_exception_test . get ( name , functions_int_default_test ) % ( " ret " , )
classes . write (
2020-04-23 08:46:21 +03:00
" if %s : \n "
" raise libvirtError( ' %s () failed ' ) \n " %
2020-04-19 16:55:12 +03:00
( test , name ) )
2011-02-16 18:57:50 +03:00
classes . write ( " return ret \n " )
2007-03-28 15:24:14 +04:00
2018-11-20 15:56:15 +03:00
elif is_python_noninteger_type ( r_type ) :
2013-12-03 15:01:44 +04:00
if name not in functions_noexcept :
2018-11-20 15:33:12 +03:00
classes . write (
2020-04-23 08:46:21 +03:00
" if ret is None: \n "
" raise libvirtError( ' %s () failed ' ) \n " %
2018-11-20 15:33:12 +03:00
( name , ) )
2011-02-16 18:57:50 +03:00
classes . write ( " return ret \n " )
2007-03-28 15:24:14 +04:00
2011-02-16 18:57:50 +03:00
else :
classes . write ( " return ret \n " )
2007-03-28 15:24:14 +04:00
2013-02-07 11:22:01 +04:00
classes . write ( " \n " )
2005-12-19 19:34:11 +03:00
2022-03-24 19:35:13 +03:00
modclasses = [ ]
if module == " libvirt " :
modclasses = classes_list
for classname in modclasses :
2020-04-20 19:28:36 +03:00
PARENTS = {
" virConnect " : " self._conn " ,
" virDomain " : " self._dom " ,
" virNetwork " : " self._net " ,
classname : " self " ,
}
2011-02-16 18:57:50 +03:00
if classname == " None " :
pass
else :
2017-01-19 18:21:01 +03:00
classes . write ( " class %s (object): \n " % ( classname ) )
2020-07-06 00:48:50 +03:00
if classname == " virStorageVol " :
2020-07-03 13:30:00 +03:00
classes . write ( " # The size (in bytes) of buffer used in sendAll(), \n " )
classes . write ( " # recvAll(), sparseSendAll() and sparseRecvAll() \n " )
classes . write ( " # methods. This corresponds to the size of payload \n " )
classes . write ( " # of a stream packet. \n " )
classes . write ( " streamBufSize = 262120 \n \n " )
2018-11-20 10:34:48 +03:00
if classname in [ " virDomain " , " virNetwork " , " virInterface " , " virStoragePool " ,
" virStorageVol " , " virNodeDevice " , " virSecret " , " virStream " ,
" virNWFilter " , " virNWFilterBinding " ] :
2017-01-19 18:21:01 +03:00
classes . write ( " def __init__(self, conn, _obj=None): \n " )
classes . write ( " self._conn = conn \n " )
2018-11-20 10:34:48 +03:00
elif classname in [ " virDomainCheckpoint " , " virDomainSnapshot " ] :
2020-10-06 12:30:59 +03:00
classes . write ( " def __init__(self, dom, _obj=None): \n " )
2017-01-19 18:21:01 +03:00
classes . write ( " self._dom = dom \n " )
classes . write ( " self._conn = dom.connect() \n " )
2018-11-20 10:34:48 +03:00
elif classname in [ " virNetworkPort " ] :
2020-04-20 19:39:54 +03:00
classes . write ( " def __init__(self, net, _obj=None) -> None: \n " )
2019-09-12 15:51:00 +03:00
classes . write ( " self._net = net \n " )
classes . write ( " self._conn = net.connect() \n " )
2020-04-20 19:39:54 +03:00
else :
classes . write ( " def __init__(self, _obj=None): \n " )
2017-01-19 18:21:01 +03:00
classes . write ( " if type(_obj).__name__ not in [ \" PyCapsule \" , \" PyCObject \" ]: \n " )
classes . write ( " raise Exception( \" Expected a wrapped C Object but got %s \" % type(_obj)) \n " )
classes . write ( " self._o = _obj \n \n " )
2018-11-20 10:34:48 +03:00
destruct = None
2013-12-03 15:01:44 +04:00
if classname in classes_destructors :
2011-02-16 18:57:50 +03:00
classes . write ( " def __del__(self): \n " )
2013-08-22 13:16:03 +04:00
classes . write ( " if self._o is not None: \n " )
2022-03-24 19:16:33 +03:00
classes . write ( " %s . %s (self._o) \n " %
( pymod , classes_destructors [ classname ] ) )
2013-02-07 11:22:01 +04:00
classes . write ( " self._o = None \n \n " )
2018-11-20 10:34:48 +03:00
destruct = classes_destructors [ classname ]
2009-09-23 20:38:47 +04:00
2013-12-03 15:01:44 +04:00
if classname not in class_skip_connect_impl :
2009-09-23 20:38:47 +04:00
# Build python safe 'connect' method
classes . write ( " def connect(self): \n " )
classes . write ( " return self._conn \n \n " )
2013-12-03 15:01:44 +04:00
if classname in class_domain_impl :
2010-05-19 17:02:30 +04:00
classes . write ( " def domain(self): \n " )
classes . write ( " return self._dom \n \n " )
2019-09-12 15:51:00 +03:00
if classname in class_network_impl :
classes . write ( " def network(self): \n " )
classes . write ( " return self._net \n \n " )
2014-12-11 14:16:12 +03:00
classes . write ( " def c_pointer(self): \n " )
classes . write ( " \" \" \" Get C pointer to underlying object \" \" \" \n " )
2022-03-24 19:16:33 +03:00
classes . write ( " return %s . %s _pointer(self._o) \n \n " %
( pymod , classname ) )
2014-12-11 14:16:12 +03:00
2011-02-16 18:57:50 +03:00
flist = function_classes [ classname ]
oldfile = " "
2020-04-20 18:42:55 +03:00
for ( index , func , name , ret , args , file , mod ) in sorted ( flist , key = functionSortKey ) :
2011-02-16 18:57:50 +03:00
#
# Do not provide as method the destructors for the class
# to avoid double free
#
if name == destruct :
2013-02-07 11:22:01 +04:00
continue
2011-02-16 18:57:50 +03:00
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 )
2018-11-20 15:56:15 +03:00
for n , ( a_name , a_type , a_info ) in enumerate ( args ) :
2011-02-16 18:57:50 +03:00
if n != index :
2018-11-20 15:56:15 +03:00
classes . write ( " , %s " % a_name )
if a_name == " flags " or is_optional_arg ( a_info ) :
if is_integral_type ( a_type ) :
2018-11-20 10:34:48 +03:00
classes . write ( " =0 " )
python: set default value to optional arguments
When prefixing with string (optional) or optional in the description
of arguments to libvirt C APIs, in python, these arguments will be
set as optional arugments, for example:
* virDomainSaveFlags:
* @domain: a domain object
* @to: path for the output file
* @dxml: (optional) XML config for adjusting guest xml used on restore
* @flags: bitwise-OR of virDomainSaveRestoreFlags
the corresponding python APIs is
restoreFlags(self, frm, dxml=None, flags=0)
The following python APIs are changed to:
blockCommit(self, disk, base, top, bandwidth=0, flags=0)
blockPull(self, disk, bandwidth=0, flags=0)
blockRebase(self, disk, base, bandwidth=0, flags=0)
migrate(self, dconn, flags=0, dname=None, uri=None, bandwidth=0)
migrate2(self, dconn, dxml=None, flags=0, dname=None, uri=None, bandwidth=0)
migrateToURI(self, duri, flags=0, dname=None, bandwidth=0)
migrateToURI2(self, dconnuri=None, miguri=None, dxml=None, flags=0, \
dname=None, bandwidth=0)
saveFlags(self, to, dxml=None, flags=0)
migrate(self, domain, flags=0, dname=None, uri=None, bandwidth=0)
migrate2(self, domain, dxml=None, flags=0, dname=None, uri=None, bandwidth=0)
restoreFlags(self, frm, dxml=None, flags=0)
2013-03-26 08:34:49 +04:00
else :
2018-11-20 10:34:48 +03:00
classes . write ( " =None " )
2011-02-16 18:57:50 +03:00
classes . write ( " ): \n " )
2013-02-07 11:22:01 +04:00
writeDoc ( module , name , args , ' ' , classes )
2018-11-20 15:56:15 +03:00
for n , ( a_name , a_type , a_info ) in enumerate ( args ) :
if a_type in classes_type :
2011-02-16 18:57:50 +03:00
if n != index :
2020-04-23 08:46:21 +03:00
classes . write ( " if %s is None: \n "
" %s __o = None \n " %
2018-11-20 15:56:15 +03:00
( a_name , a_name ) )
2020-04-23 08:46:21 +03:00
classes . write ( " else: \n "
" %s __o = %s %s \n " %
2018-11-20 15:56:15 +03:00
( a_name , a_name , classes_type [ a_type ] [ 0 ] ) )
r_type , r_info , r_field = ret
if r_type != " void " :
2013-02-07 11:22:01 +04:00
classes . write ( " ret = " )
2011-02-16 18:57:50 +03:00
else :
2013-02-07 11:22:01 +04:00
classes . write ( " " )
2022-03-24 19:16:33 +03:00
classes . write ( " %s . %s ( " % ( pymod , name ) )
2018-11-20 15:56:15 +03:00
for n , ( a_name , a_type , a_info ) in enumerate ( args ) :
2011-02-16 18:57:50 +03:00
if n != 0 :
2013-02-07 11:22:01 +04:00
classes . write ( " , " )
2011-02-16 18:57:50 +03:00
if n != index :
2018-11-20 15:56:15 +03:00
classes . write ( " %s " % a_name )
if a_type in classes_type :
2013-02-07 11:22:01 +04:00
classes . write ( " __o " )
2011-02-16 18:57:50 +03:00
else :
2013-02-07 11:22:01 +04:00
classes . write ( " self " )
2018-11-20 15:56:15 +03:00
if a_type in classes_type :
classes . write ( classes_type [ a_type ] [ 0 ] )
2013-02-07 11:22:01 +04:00
classes . write ( " ) \n " )
2007-03-28 15:24:14 +04:00
2009-04-01 14:39:12 +04:00
if name == " virConnectClose " :
classes . write ( " self._o = None \n " )
2007-03-28 15:24:14 +04:00
# For functions returning object types:
2018-11-20 15:56:15 +03:00
if r_type != " void " :
if r_type in classes_type :
2011-02-16 18:57:50 +03:00
#
# Raise an exception
#
2013-12-03 15:01:44 +04:00
if name in functions_noexcept :
2011-02-16 18:57:50 +03:00
classes . write (
2020-04-23 08:46:21 +03:00
" if ret is None: \n "
" return None \n " )
2011-02-16 18:57:50 +03:00
else :
2018-11-21 09:55:57 +03:00
classes . write (
2020-04-23 08:46:21 +03:00
" if ret is None: \n "
" raise libvirtError( ' %s () failed ' ) \n " %
2018-11-21 09:55:57 +03:00
( name , ) )
2005-12-19 19:34:11 +03:00
2011-02-16 18:57:50 +03:00
#
# generate the returned class wrapper for the object
#
2020-04-20 19:28:36 +03:00
tinfo = classes_type [ r_type ]
2013-02-07 11:22:01 +04:00
classes . write ( " __tmp = " )
2020-04-20 19:28:36 +03:00
classes . write ( tinfo [ 1 ] % { " o " : " ret " , " p " : PARENTS [ tinfo [ 3 ] ] } )
2013-02-07 11:22:01 +04:00
classes . write ( " \n " )
2005-12-19 19:34:11 +03:00
2011-02-16 18:57:50 +03:00
#
# return the class
#
2013-02-07 11:22:01 +04:00
classes . write ( " return __tmp \n " )
2007-03-28 15:24:14 +04:00
# For functions returning an integral type there
# are several things that we can do, depending on
# the contents of functions_int_*:
2018-11-20 15:56:15 +03:00
elif is_integral_type ( r_type ) :
2013-12-03 15:01:44 +04:00
if name not in functions_noexcept :
2018-11-21 09:55:57 +03:00
test = functions_int_exception_test . get ( name , functions_int_default_test ) % ( " ret " , )
classes . write (
2020-04-23 08:46:21 +03:00
" if %s : \n "
" raise libvirtError( ' %s () failed ' ) \n " %
2018-11-21 09:55:57 +03:00
( test , name ) )
2007-03-28 15:24:14 +04:00
2018-11-20 10:34:48 +03:00
classes . write ( " return ret \n " )
2007-03-28 15:24:14 +04:00
2018-11-20 15:56:15 +03:00
elif is_python_noninteger_type ( r_type ) :
2013-12-03 15:01:44 +04:00
if name not in functions_noexcept :
2018-11-21 09:55:57 +03:00
classes . write (
2020-04-23 08:46:21 +03:00
" if ret is None: \n "
" raise libvirtError( ' %s () failed ' ) \n " %
2018-11-21 09:55:57 +03:00
( name , ) )
2007-03-28 15:24:14 +04:00
2018-11-20 10:34:48 +03:00
classes . write ( " return ret \n " )
2011-02-16 18:57:50 +03:00
else :
2013-02-07 11:22:01 +04:00
classes . write ( " return ret \n " )
2007-03-28 15:24:14 +04:00
2013-02-07 11:22:01 +04:00
classes . write ( " \n " )
2008-10-31 13:13:45 +03:00
# Append "<classname>.py" to class def, iff it exists
2022-03-24 19:35:13 +03:00
class_override = " %s -override- %s .py " % ( module , classname )
2024-04-26 17:56:43 +03:00
extra = openSourceFile ( class_override , " r " , True )
if extra :
2018-11-20 10:34:48 +03:00
classes . write ( " # \n " )
classes . write ( " # %s methods from %s .py (hand coded) \n " % ( classname , classname ) )
classes . write ( " # \n " )
2013-11-27 03:26:34 +04:00
cached = None
# Since we compile with older libvirt, we don't want to pull
# in manually written python methods which call C methods
# that don't exist. This code attempts to detect which
# methods to skip by looking at the libvirtmod.XXXX calls
2018-11-20 12:32:36 +03:00
def shouldSkip ( lines : List [ str ] ) - > bool :
2013-11-27 03:26:34 +04:00
for line in lines :
2022-03-24 19:16:33 +03:00
offset = line . find ( pymod + " . " )
2013-11-27 03:26:34 +04:00
if offset != - 1 :
func = line [ offset + 11 : ]
offset = func . find ( " ( " )
func = func [ 0 : offset ]
2022-03-24 21:04:31 +03:00
if not skip_c_impl ( func ) and func != " virConnectListDomains " :
2013-11-27 03:26:34 +04:00
return True
return False
for line in extra . readlines ( ) :
offset = line . find ( " def " )
if offset != - 1 :
2018-11-20 10:34:48 +03:00
name = line [ offset + 5 : ]
2013-11-27 03:26:34 +04:00
offset = name . find ( " ( " )
name = name [ 0 : offset ]
2018-11-20 17:39:36 +03:00
if cached :
2013-11-27 03:26:34 +04:00
if not shouldSkip ( cached ) :
classes . writelines ( cached )
if name == " __del__ " :
cached = None
classes . write ( line )
else :
cached = [ line ]
else :
2018-11-20 17:39:36 +03:00
if cached :
2013-11-27 03:26:34 +04:00
cached . append ( line )
else :
classes . write ( line )
2018-11-20 17:03:50 +03:00
if cached is not None and not shouldSkip ( cached ) :
2013-11-27 03:26:34 +04:00
classes . writelines ( cached )
2009-10-02 21:05:03 +04:00
classes . write ( " \n " )
2008-10-31 13:13:45 +03:00
extra . close ( )
2005-12-19 19:34:11 +03:00
2022-03-24 19:35:13 +03:00
direct_functions = { }
if module != " libvirt " :
direct_functions = functions
2014-02-20 19:35:02 +04:00
2022-03-24 19:35:13 +03:00
classes . write ( " # \n # Functions from module %s \n # \n \n " % module )
2014-09-01 23:24:42 +04:00
2011-09-09 15:09:44 +04:00
#
# Generate functions directly, no classes
#
2022-03-24 19:35:13 +03:00
for name , ( desc , ret , args , file , mod , cond ) in sorted ( direct_functions . items ( ) ) :
2022-03-24 21:04:31 +03:00
if skip_py_impl ( name ) :
continue
2020-04-23 08:41:04 +03:00
func = nameFixup ( name , ' None ' , ' ' , ' ' )
2022-03-24 19:35:13 +03:00
classes . write ( " def %s ( " % func )
2018-11-20 15:56:15 +03:00
for n , ( a_name , a_type , a_info ) in enumerate ( args ) :
2011-09-09 15:09:44 +04:00
if n != 0 :
2022-03-24 19:35:13 +03:00
classes . write ( " , " )
classes . write ( " %s " % a_name )
classes . write ( " ): \n " )
writeDoc ( module , name , args , ' ' , classes )
2011-09-09 15:09:44 +04:00
2018-11-20 15:56:15 +03:00
r_type , r_info , r_field = ret
if r_type != " void " :
2022-03-24 19:35:13 +03:00
classes . write ( " ret = " )
2011-09-09 15:09:44 +04:00
else :
2022-03-24 19:35:13 +03:00
classes . write ( " " )
classes . write ( " %s . %s ( " % ( pymod , name ) )
2011-09-09 15:09:44 +04:00
conn = None
2018-11-20 15:56:15 +03:00
for n , ( a_name , a_type , a_info ) in enumerate ( args ) :
if a_type == " virConnectPtr " :
conn = a_name
2011-09-09 15:09:44 +04:00
if n != 0 :
2022-03-24 19:35:13 +03:00
classes . write ( " , " )
2018-11-20 15:56:15 +03:00
if a_type in [ " virDomainPtr " , " virConnectPtr " ] :
2011-09-09 15:09:44 +04:00
# FIXME: This might have problem if the function
# has multiple args which are objects.
2022-03-24 19:35:13 +03:00
classes . write ( " %s . %s " % ( a_name , " _o " ) )
2011-09-09 15:09:44 +04:00
else :
2022-03-24 19:35:13 +03:00
classes . write ( " %s " % a_name )
classes . write ( " ) \n " )
2011-09-09 15:09:44 +04:00
2018-11-20 15:56:15 +03:00
if r_type != " void " :
2022-03-24 19:35:13 +03:00
classes . write ( " if ret is None: \n "
2020-04-23 08:46:21 +03:00
" raise libvirt.libvirtError( ' %s () failed ' ) \n " % ( name , ) )
2018-11-20 15:56:15 +03:00
if r_type == " virDomainPtr " :
2022-03-24 19:35:13 +03:00
classes . write ( " __tmp = libvirt.virDomain( %s , _obj=ret) \n " % ( conn , ) )
classes . write ( " return __tmp \n " )
2011-09-09 15:09:44 +04:00
else :
2022-03-24 19:35:13 +03:00
classes . write ( " return ret \n " )
2011-09-09 15:09:44 +04:00
2022-03-24 19:35:13 +03:00
classes . write ( " \n " )
2011-09-09 15:09:44 +04:00
#
# Generate enum constants
#
2022-03-24 19:35:13 +03:00
def enumsSortKey ( data : Tuple [ str , EnumValue ] ) - > Tuple [ Union [ int , float ] , str ] :
try :
value = int ( data [ 1 ] ) # type: Union[int, float]
except ValueError :
value = float ( ' inf ' )
return value , data [ 0 ]
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 17:15:19 +04:00
2022-03-24 19:35:13 +03:00
# Resolve only one level of reference
def resolveEnum ( enum : EnumType , data : EnumType ) - > EnumType :
for name , val in enum . items ( ) :
try :
int ( val )
except ValueError :
enum [ name ] = data [ val ] # type: ignore
return enum
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 17:15:19 +04:00
2022-03-24 19:35:13 +03:00
enumvals = list ( enums . items ( ) )
# convert list of dicts to one dict
enumData = { } # type: EnumType
for type , enum in enumvals :
enumData . update ( enum )
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 17:15:19 +04:00
2022-03-24 19:35:13 +03:00
for type , enum in sorted ( enumvals ) :
classes . write ( " # %s \n " % type )
items = sorted ( resolveEnum ( enum , enumData ) . items ( ) , key = enumsSortKey )
if items [ - 1 ] [ 0 ] . endswith ( ' _LAST ' ) :
del items [ - 1 ]
for name , value in items :
classes . write ( " %s = %s \n " % ( name , value ) )
classes . write ( " \n " )
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 17:15:19 +04:00
2022-03-24 19:35:13 +03:00
if params :
classes . write ( " # typed parameter names \n " )
for name , value in params :
classes . write ( " %s = \" %s \" \n " % ( name , value ) )
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 17:15:19 +04:00
2022-03-24 19:35:13 +03:00
classes . close ( )
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 17:15:19 +04:00
2022-03-24 19:35:13 +03:00
if sys . argv [ 1 ] not in [ " libvirt " , " libvirt-lxc " , " libvirt-qemu " ] :
print ( " ERROR: unknown module %s " % sys . argv [ 1 ] )
sys . exit ( 1 )
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 17:15:19 +04:00
2024-04-26 17:56:43 +03:00
if len ( sys . argv ) == 6 :
buildDir = sys . argv [ 5 ]
if len ( sys . argv ) > = 5 :
sourceDir = sys . argv [ 4 ]
2022-03-24 19:58:15 +03:00
load_apis ( sys . argv [ 1 ] , sys . argv [ 2 ] )
2022-03-24 20:40:31 +03:00
if validate_functions ( ) < 0 :
sys . exit ( 1 )
2018-11-20 12:03:29 +03:00
quiet = False
2013-11-12 22:21:45 +04:00
if not os . path . exists ( " build " ) :
os . mkdir ( " build " )
2013-11-19 02:16:23 +04:00
2022-03-23 15:15:36 +03:00
output = None
2024-04-26 17:56:43 +03:00
if len ( sys . argv ) > = 4 :
2022-03-23 15:15:36 +03:00
output = sys . argv [ 3 ]
2024-04-26 17:56:43 +03:00
if output == " c " or output == " c+py " or output is None :
2022-03-23 15:15:36 +03:00
emit_c_code ( sys . argv [ 1 ] )
2024-04-26 17:56:43 +03:00
if output == " py " or output == " c+py " or output is None :
2022-03-23 15:15:36 +03:00
emit_py_code ( sys . argv [ 1 ] )
2013-11-19 02:16:23 +04:00
2008-01-21 18:55:53 +03:00
sys . exit ( 0 )