1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-11-08 19:26:48 +00:00

fix(vrtManager): a volume upload aborts its stream when the volume cannot be made

upload_volume opens the libvirt stream before it creates the volume, but
created the volume outside the block that aborts the stream: a pool that
refused the volume (full, a name taken) left an unfinished stream to be
freed. The creation is now inside that block.
This commit is contained in:
catborise 2026-11-05 08:48:38 +03:00
parent 297f9a8a53
commit d4b9edc3e5
2 changed files with 18 additions and 6 deletions

View file

@ -1040,12 +1040,13 @@ class wvmConnect(object):
stream, which every connection type carries. A failed write leaves
no volume."""
stream = self.wvm.newStream(0)
vol = pool.createXML(
f"<volume><name>{util.xml_escape(name)}</name><capacity>{len(data)}</capacity>"
"<target><format type='raw'/></target></volume>",
0,
)
vol = None
try:
vol = pool.createXML(
f"<volume><name>{util.xml_escape(name)}</name><capacity>{len(data)}</capacity>"
"<target><format type='raw'/></target></volume>",
0,
)
vol.upload(stream, 0, len(data), 0)
stream.sendAll(lambda _stream, size, buffer: buffer.read(size), io.BytesIO(data))
stream.finish()
@ -1053,7 +1054,8 @@ class wvmConnect(object):
# libvirt: a stream that did not finish is aborted before it is freed
with contextlib.suppress(libvirtError):
stream.abort()
vol.delete(0)
if vol is not None:
vol.delete(0)
raise
return vol

View file

@ -81,6 +81,16 @@ class UploadVolumeTestCase(unittest.TestCase):
conn.wvm.newStream.return_value.abort.assert_called_once_with()
def test_a_volume_that_cannot_be_made_aborts_the_stream(self):
conn = wvmConnect.__new__(wvmConnect)
conn.wvm = MagicMock()
pool = MagicMock()
pool.createXML.side_effect = libvirtError("pool is full")
with self.assertRaises(libvirtError):
conn.upload_volume(pool, "a.iso", b"data")
conn.wvm.newStream.return_value.abort.assert_called_once_with()
class DeleteWithDisksTestCase(unittest.TestCase):
def vm(self, seed_in_pool=True):
from vrtManager.instance import wvmInstance