I'm trying to write some Python code that uses libvirt-python
to manage external snapshots with the KVM APIs.
I'm not sure of what to do in order to delete (aka merge) a certain snapshot. Let's say we have mainly 2 case in the following scenario: base <- snap_a <- snap-b <- top
(as shown in this webpage).
- I want to merge
snap_a
and snap_b
(b is the active one). The result should have base
as backing file in the snapshot chain.
- I want to merge
base
and snap_a
(none of them is active). The result should keep snap_b
as active snapshot, which has base
as backing file.
In the first case I lost my base
backing file, while in the second one i got this error: Failed to merge snapshot: invalid argument: active commit requested but '/var/lib/nova/instances/b9c9cd3b-1102-4084-a7a9-6e85c179ac9c/disk.snap_system_1610446663' is not active
(snap_system_numbers
here is like snap_a in my example).
This is my merging function:
def snapshot_merge(instance_name: str, snapshot_name: str):
# Getting the connection to qemu
conn, dom = open_qemu_connection(instance_name)
if conn is not None and dom is not None:
logging.info(
'Merging domain {} from snapshot {}'
.format(instance_name, snapshot_name))
# Merge snapshot (Block commit, first phase)
# Get the vda path from my custom function
disk_path = get_vda_path(dom)
top = disk_path+'.'+snapshot_name
disk = 'vda'
bandwith = 0
# Check if snapshot in input is the active/current one. Also setting flags
snapshot = dom.snapshotCurrent()
if snapshot.getName() == snapshot_name:
bc_flags = (libvirt.VIR_DOMAIN_BLOCK_COMMIT_ACTIVE
+ libvirt.VIR_DOMAIN_BLOCK_COMMIT_SHALLOW)
else:
bc_flags = 0
try:
dom.blockCommit(disk,
None,
top,
bandwith,
bc_flags)
logging.info('Snapshot merged')
except libvirt.libvirtError as e:
logging.info('Failed to merge snapshot: %s' % e)
close_qemu_connection(conn)
raise HTTPException(status_code=500, detail=ERR_MERGE)
# Merge snapshot (Pivoting, second phase)
piv_flags = libvirt.VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT
# Wait for ready state
time.sleep(5)
try:
dom.blockJobAbort(disk, piv_flags)
logging.info('Snapshot pivoted')
snapshot_delete(dom, snapshot_name, top)
return {"snapshot_name": snapshot_name}
except libvirt.libvirtError as e:
logging.info('Failed to pivot snapshot: %s' % e)
# TODO snapshot_delete(dom, snapshot_name, top)
raise HTTPException(status_code=500, detail=ERR_PIVOT)
finally:
close_qemu_connection(conn)
else:
logging.info('Process failed')
raise HTTPException(status_code=500, detail=ERR_CONN)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…