Skip to content

Commit 358a864

Browse files
committed
Add virDomainCheckpoint APIs
Copies heavily from existing virDomainSnapshot handling, regarding what special cases the generator has to be taught and what overrides need to be written. Signed-off-by: Eric Blake <[email protected]> Reviewed-by: Daniel P. Berrangé <[email protected]>
1 parent 5e9d1aa commit 358a864

10 files changed

+196
-7
lines changed

Diff for: HACKING

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ hand written source files
2828
the virConnect class
2929
- libvirt-override-virDomain.py - high level overrides in
3030
the virDomain class
31+
- libvirt-override-virDomainCheckpoint.py - high level overrides in
32+
the virDomainCheckpoint class
3133
- libvirt-override-virDomainSnapshot.py - high level overrides in
3234
the virDomainSnapshot class
3335
- libvirt-override-virStoragePool.py - high level overrides in

Diff for: MANIFEST.in

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ include libvirt-override.c
2323
include libvirt-override.py
2424
include libvirt-override-virConnect.py
2525
include libvirt-override-virDomain.py
26+
include libvirt-override-virDomainCheckpoint.py
2627
include libvirt-override-virDomainSnapshot.py
2728
include libvirt-override-virNetwork.py
2829
include libvirt-override-virStoragePool.py

Diff for: generator.py

+27-4
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"libvirt",
3636
"libvirt-common",
3737
"libvirt-domain",
38+
"libvirt-domain-checkpoint",
3839
"libvirt-domain-snapshot",
3940
"libvirt-event",
4041
"libvirt-host",
@@ -368,6 +369,10 @@ def qemu_enum(type, name, value):
368369
'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
369370
'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"),
370371

372+
'virDomainCheckpointPtr': ('O', "virDomainCheckpoint", "virDomainCheckpointPtr", "virDomainCheckpointPtr"),
373+
'virDomainCheckpoint *': ('O', "virDomainCheckpoint", "virDomainCheckpointPtr", "virDomainCheckpointPtr"),
374+
'const virDomainCheckpoint *': ('O', "virDomainCheckpoint", "virDomainCheckpointPtr", "virDomainCheckpointPtr"),
375+
371376
'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
372377
'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
373378
'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"),
@@ -542,6 +547,8 @@ def qemu_enum(type, name, value):
542547
'virSaveLastError', # We have our own python error wrapper
543548
'virFreeError', # Only needed if we use virSaveLastError
544549
'virConnectListAllDomains', # overridden in virConnect.py
550+
'virDomainListAllCheckpoints', # overridden in virDomain.py
551+
'virDomainCheckpointListAllChildren', # overridden in virDomainCheckpoint.py
545552
'virDomainListAllSnapshots', # overridden in virDomain.py
546553
'virDomainSnapshotListAllChildren', # overridden in virDomainSnapshot.py
547554
'virConnectListAllStoragePools', # overridden in virConnect.py
@@ -590,6 +597,7 @@ def qemu_enum(type, name, value):
590597
"virStoragePoolRef",
591598
"virStorageVolRef",
592599
"virStreamRef",
600+
"virDomainCheckpointRef",
593601
"virDomainSnapshotRef",
594602

595603
# This functions shouldn't be called via the bindings (and even the docs
@@ -603,6 +611,8 @@ def qemu_enum(type, name, value):
603611
"virNWFilterGetConnect",
604612
"virStoragePoolGetConnect",
605613
"virStorageVolGetConnect",
614+
"virDomainCheckpointGetConnect",
615+
"virDomainCheckpointGetDomain",
606616
"virDomainSnapshotGetConnect",
607617
"virDomainSnapshotGetDomain",
608618

@@ -1034,6 +1044,8 @@ def buildStubs(module, api_xml):
10341044
"virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"),
10351045
"virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"),
10361046
"virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"),
1047+
"virDomainCheckpointPtr": ("._o", "virDomainCheckpoint(self,_obj=%s)", "virDomainCheckpoint"),
1048+
"virDomainCheckpoint *": ("._o", "virDomainCheckpoint(self, _obj=%s)", "virDomainCheckpoint"),
10371049
"virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"),
10381050
"virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"),
10391051
}
@@ -1042,7 +1054,7 @@ def buildStubs(module, api_xml):
10421054
"virInterface", "virStoragePool", "virStorageVol",
10431055
"virConnect", "virNodeDevice", "virSecret",
10441056
"virNWFilter", "virNWFilterBinding",
1045-
"virStream", "virDomainSnapshot"]
1057+
"virStream", "virDomainCheckpoint", "virDomainSnapshot"]
10461058

10471059
classes_destructors = {
10481060
"virDomain": "virDomainFree",
@@ -1055,6 +1067,7 @@ def buildStubs(module, api_xml):
10551067
"virSecret": "virSecretFree",
10561068
"virNWFilter": "virNWFilterFree",
10571069
"virNWFilterBinding": "virNWFilterBindingFree",
1070+
"virDomainCheckpoint": "virDomainCheckpointFree",
10581071
"virDomainSnapshot": "virDomainSnapshotFree",
10591072
# We hand-craft __del__ for this one
10601073
#"virStream": "virStreamFree",
@@ -1065,6 +1078,7 @@ def buildStubs(module, api_xml):
10651078
}
10661079

10671080
class_domain_impl = {
1081+
"virDomainCheckpoint": True,
10681082
"virDomainSnapshot": True,
10691083
}
10701084

@@ -1189,6 +1203,15 @@ def nameFixup(name, classe, type, file):
11891203
elif name[0:12] == "virDomainGet":
11901204
func = name[12:]
11911205
func = func[0:1].lower() + func[1:]
1206+
elif name[0:31] == "virDomainCheckpointLookupByName":
1207+
func = name[9:]
1208+
func = func[0:1].lower() + func[1:]
1209+
elif name[0:28] == "virDomainCheckpointCreateXML":
1210+
func = name[9:]
1211+
func = func[0:1].lower() + func[1:]
1212+
elif name[0:19] == "virDomainCheckpoint":
1213+
func = name[19:]
1214+
func = func[0:1].lower() + func[1:]
11921215
elif name[0:29] == "virDomainSnapshotLookupByName":
11931216
func = name[9:]
11941217
func = func[0:1].lower() + func[1:]
@@ -1525,7 +1548,7 @@ def buildWrappers(module):
15251548
"virStorageVol", "virNodeDevice", "virSecret","virStream",
15261549
"virNWFilter", "virNWFilterBinding" ]:
15271550
classes.write(" def __init__(self, conn, _obj=None):\n")
1528-
elif classname in [ 'virDomainSnapshot' ]:
1551+
elif classname in [ "virDomainCheckpoint", "virDomainSnapshot" ]:
15291552
classes.write(" def __init__(self, dom, _obj=None):\n")
15301553
else:
15311554
classes.write(" def __init__(self, _obj=None):\n")
@@ -1537,7 +1560,7 @@ def buildWrappers(module):
15371560
classes.write(" self._conn = conn\n" + \
15381561
" if not isinstance(conn, virConnect):\n" + \
15391562
" self._conn = conn._conn\n")
1540-
elif classname in [ "virDomainSnapshot" ]:
1563+
elif classname in [ "virDomainCheckpoint", "virDomainSnapshot" ]:
15411564
classes.write(" self._dom = dom\n")
15421565
classes.write(" self._conn = dom.connect()\n")
15431566
classes.write(" if type(_obj).__name__ not in [\"PyCapsule\", \"PyCObject\"]:\n")
@@ -1665,7 +1688,7 @@ def buildWrappers(module):
16651688
classes.write(
16661689
" if ret is None:raise libvirtError('%s() failed', vol=self)\n" %
16671690
(name))
1668-
elif classname == "virDomainSnapshot":
1691+
elif classname in [ "virDomainCheckpoint", "virDomainSnapshot"]:
16691692
classes.write(
16701693
" if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" %
16711694
(name))

Diff for: libvirt-override-api.xml

+12
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,18 @@
576576
<arg name='flags' type='unsigned int' info='flags'/>
577577
<return type='int' info="0 on success, -1 on error"/>
578578
</function>
579+
<function name='virDomainListAllCheckpoints' file='python'>
580+
<info>returns the list of checkpoints for the given domain</info>
581+
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>
582+
<arg name='flags' type='unsigned int' info='flags'/>
583+
<return type='char *' info='the list of checkpoints or None in case of error'/>
584+
</function>
585+
<function name='virDomainCheckpointListAllChildren' file='python'>
586+
<info>collect the list of child checkpoint names for the given checkpoint</info>
587+
<arg name='checkpoint' type='virDomainCheckpointPtr' info='pointer to the checkpoint'/>
588+
<arg name='flags' type='unsigned int' info='flags'/>
589+
<return type='char *' info='the list of checkpoints or None in case of error'/>
590+
</function>
579591
<function name='virDomainGetBlockJobInfo' file='python'>
580592
<info>Get progress information for a block job</info>
581593
<arg name='dom' type='virDomainPtr' info='pointer to the domain'/>

Diff for: libvirt-override-virDomain.py

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ def listAllSnapshots(self, flags=0):
1111
return retlist
1212

1313

14+
def listAllCheckpoints(self, flags=0):
15+
"""List all checkpoints and returns a list of checkpoint objects"""
16+
ret = libvirtmod.virDomainListAllCheckpoints(self._o, flags)
17+
if ret is None:
18+
raise libvirtError("virDomainListAllCheckpoints() failed", conn=self)
19+
20+
retlist = list()
21+
for chkptr in ret:
22+
retlist.append(virDomainCheckpoint(self, _obj=chkptr))
23+
24+
return retlist
25+
26+
1427
def createWithFiles(self, files, flags=0):
1528
"""Launch a defined domain. If the call succeeds the domain moves from the
1629
defined to the running domains pools.

Diff for: libvirt-override-virDomainCheckpoint.py

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
def getConnect(self):
2+
"""Get the connection that owns the domain that a checkpoint was created for"""
3+
return self.connect()
4+
5+
def getDomain(self):
6+
"""Get the domain that a checkpoint was created for"""
7+
return self.domain()
8+
9+
def listAllChildren(self, flags=0):
10+
"""List all child checkpoints and returns a list of checkpoint objects"""
11+
ret = libvirtmod.virDomainCheckpointListAllChildren(self._o, flags)
12+
if ret is None:
13+
raise libvirtError("virDomainCheckpointListAllChildren() failed", conn=self)
14+
15+
retlist = list()
16+
for chkptr in ret:
17+
retlist.append(virDomainCheckpoint(self, _obj=chkptr))
18+
19+
return retlist

Diff for: libvirt-override.c

+96
Original file line numberDiff line numberDiff line change
@@ -2325,6 +2325,98 @@ libvirt_virConnectListDefinedDomains(PyObject *self ATTRIBUTE_UNUSED,
23252325
goto cleanup;
23262326
}
23272327

2328+
#if LIBVIR_CHECK_VERSION(5, 6, 0)
2329+
static PyObject *
2330+
libvirt_virDomainListAllCheckpoints(PyObject *self ATTRIBUTE_UNUSED,
2331+
PyObject *args)
2332+
{
2333+
PyObject *py_retval = NULL;
2334+
virDomainCheckpointPtr *chks = NULL;
2335+
int c_retval;
2336+
ssize_t i;
2337+
virDomainPtr dom;
2338+
PyObject *pyobj_dom;
2339+
unsigned int flags;
2340+
2341+
if (!PyArg_ParseTuple(args, (char *)"OI:virDomainListAllCheckpoints",
2342+
&pyobj_dom, &flags))
2343+
return NULL;
2344+
dom = (virDomainPtr) PyvirDomain_Get(pyobj_dom);
2345+
2346+
LIBVIRT_BEGIN_ALLOW_THREADS;
2347+
c_retval = virDomainListAllCheckpoints(dom, &chks, flags);
2348+
LIBVIRT_END_ALLOW_THREADS;
2349+
2350+
if (c_retval < 0)
2351+
return VIR_PY_NONE;
2352+
2353+
if (!(py_retval = PyList_New(c_retval)))
2354+
goto cleanup;
2355+
2356+
for (i = 0; i < c_retval; i++) {
2357+
VIR_PY_LIST_SET_GOTO(py_retval, i,
2358+
libvirt_virDomainCheckpointPtrWrap(chks[i]), error);
2359+
chks[i] = NULL;
2360+
}
2361+
2362+
cleanup:
2363+
for (i = 0; i < c_retval; i++)
2364+
if (chks[i])
2365+
virDomainCheckpointFree(chks[i]);
2366+
VIR_FREE(chks);
2367+
return py_retval;
2368+
2369+
error:
2370+
Py_CLEAR(py_retval);
2371+
goto cleanup;
2372+
}
2373+
2374+
static PyObject *
2375+
libvirt_virDomainCheckpointListAllChildren(PyObject *self ATTRIBUTE_UNUSED,
2376+
PyObject *args)
2377+
{
2378+
PyObject *py_retval = NULL;
2379+
virDomainCheckpointPtr *chks = NULL;
2380+
int c_retval;
2381+
ssize_t i;
2382+
virDomainCheckpointPtr parent;
2383+
PyObject *pyobj_parent;
2384+
unsigned int flags;
2385+
2386+
if (!PyArg_ParseTuple(args, (char *)"OI:virDomainCheckpointListAllChildren",
2387+
&pyobj_parent, &flags))
2388+
return NULL;
2389+
parent = (virDomainCheckpointPtr) PyvirDomainCheckpoint_Get(pyobj_parent);
2390+
2391+
LIBVIRT_BEGIN_ALLOW_THREADS;
2392+
c_retval = virDomainCheckpointListAllChildren(parent, &chks, flags);
2393+
LIBVIRT_END_ALLOW_THREADS;
2394+
2395+
if (c_retval < 0)
2396+
return VIR_PY_NONE;
2397+
2398+
if (!(py_retval = PyList_New(c_retval)))
2399+
goto cleanup;
2400+
2401+
for (i = 0; i < c_retval; i++) {
2402+
VIR_PY_LIST_SET_GOTO(py_retval, i,
2403+
libvirt_virDomainCheckpointPtrWrap(chks[i]), error);
2404+
chks[i] = NULL;
2405+
}
2406+
2407+
cleanup:
2408+
for (i = 0; i < c_retval; i++)
2409+
if (chks[i])
2410+
virDomainCheckpointFree(chks[i]);
2411+
VIR_FREE(chks);
2412+
return py_retval;
2413+
2414+
error:
2415+
Py_CLEAR(py_retval);
2416+
goto cleanup;
2417+
}
2418+
#endif /* LIBVIR_CHECK_VERSION(5, 6, 0) */
2419+
23282420
static PyObject *
23292421
libvirt_virDomainSnapshotListNames(PyObject *self ATTRIBUTE_UNUSED,
23302422
PyObject *args)
@@ -10238,6 +10330,10 @@ static PyMethodDef libvirtMethods[] = {
1023810330
#if LIBVIR_CHECK_VERSION(1, 0, 3)
1023910331
{(char *) "virDomainGetJobStats", libvirt_virDomainGetJobStats, METH_VARARGS, NULL},
1024010332
#endif /* LIBVIR_CHECK_VERSION(1, 0, 3) */
10333+
#if LIBVIR_CHECK_VERSION(5, 6, 0)
10334+
{(char *) "virDomainListAllCheckpoints", libvirt_virDomainListAllCheckpoints, METH_VARARGS, NULL},
10335+
{(char *) "virDomainCheckpointListAllChildren", libvirt_virDomainCheckpointListAllChildren, METH_VARARGS, NULL},
10336+
#endif /* LIBVIR_CHECK_VERSION(5, 6, 0) */
1024110337
{(char *) "virDomainSnapshotListNames", libvirt_virDomainSnapshotListNames, METH_VARARGS, NULL},
1024210338
#if LIBVIR_CHECK_VERSION(0, 9, 13)
1024310339
{(char *) "virDomainListAllSnapshots", libvirt_virDomainListAllSnapshots, METH_VARARGS, NULL},

Diff for: sanitytest.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ def get_libvirt_api_xml_path():
249249
# Remove 'Get' prefix from most APIs, except those in virConnect
250250
# and virDomainSnapshot namespaces which stupidly used a different
251251
# convention which we now can't fix without breaking API
252-
if func[0:3] == "Get" and klass not in ["virConnect", "virDomainSnapshot", "libvirt"]:
252+
if func[0:3] == "Get" and klass not in ["virConnect", "virDomainCheckpoint", "virDomainSnapshot", "libvirt"]:
253253
if func not in ["GetCPUStats", "GetTime"]:
254254
func = func[3:]
255255

@@ -266,7 +266,7 @@ def get_libvirt_api_xml_path():
266266
if klass != "virDomain":
267267
func = klass[3:] + func
268268

269-
if klass == "virDomainSnapshot":
269+
if klass in ["virDomainCheckpoint", "virDomainSnapshot"]:
270270
klass = "virDomain"
271271
func = func[6:]
272272
elif klass == "virStorageVol" and func in ["StorageVolCreateXMLFrom", "StorageVolCreateXML"]:
@@ -300,7 +300,7 @@ def get_libvirt_api_xml_path():
300300
if func[0:6] == "Change":
301301
klass = "virConnect"
302302

303-
# Need to special case the snapshot APIs
303+
# Need to special case the checkpoint and snapshot APIs
304304
if klass == "virDomainSnapshot" and func in ["Current", "ListNames", "Num"]:
305305
klass = "virDomain"
306306
func = "snapshot" + func

Diff for: typewrappers.c

+13
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,19 @@ libvirt_virStreamPtrWrap(virStreamPtr node)
581581
return ret;
582582
}
583583

584+
PyObject *
585+
libvirt_virDomainCheckpointPtrWrap(virDomainCheckpointPtr node)
586+
{
587+
PyObject *ret;
588+
589+
if (node == NULL) {
590+
return VIR_PY_NONE;
591+
}
592+
593+
ret = libvirt_buildPyObject(node, "virDomainCheckpointPtr", NULL);
594+
return ret;
595+
}
596+
584597
PyObject *
585598
libvirt_virDomainSnapshotPtrWrap(virDomainSnapshotPtr node)
586599
{

Diff for: typewrappers.h

+10
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,15 @@ typedef struct {
140140
} PyvirStream_Object;
141141

142142

143+
#define PyvirDomainCheckpoint_Get(v) (((v) == Py_None) ? NULL : \
144+
(((PyvirDomainCheckpoint_Object *)(v))->obj))
145+
146+
typedef struct {
147+
PyObject_HEAD
148+
virDomainCheckpointPtr obj;
149+
} PyvirDomainCheckpoint_Object;
150+
151+
143152
#define PyvirDomainSnapshot_Get(v) (((v) == Py_None) ? NULL : \
144153
(((PyvirDomainSnapshot_Object *)(v))->obj))
145154

@@ -217,6 +226,7 @@ PyObject * libvirt_virSecretPtrWrap(virSecretPtr node);
217226
PyObject * libvirt_virNWFilterPtrWrap(virNWFilterPtr node);
218227
PyObject * libvirt_virNWFilterBindingPtrWrap(virNWFilterBindingPtr node);
219228
PyObject * libvirt_virStreamPtrWrap(virStreamPtr node);
229+
PyObject * libvirt_virDomainCheckpointPtrWrap(virDomainCheckpointPtr node);
220230
PyObject * libvirt_virDomainSnapshotPtrWrap(virDomainSnapshotPtr node);
221231

222232

0 commit comments

Comments
 (0)