diff --git a/vrtManager/connection.py b/vrtManager/connection.py index 91032870..6eb7349e 100644 --- a/vrtManager/connection.py +++ b/vrtManager/connection.py @@ -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"{util.xml_escape(name)}{len(data)}" - "", - 0, - ) + vol = None try: + vol = pool.createXML( + f"{util.xml_escape(name)}{len(data)}" + "", + 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 diff --git a/vrtManager/tests/test_cloud_init_seed.py b/vrtManager/tests/test_cloud_init_seed.py index 6717655b..13b8dfbe 100644 --- a/vrtManager/tests/test_cloud_init_seed.py +++ b/vrtManager/tests/test_cloud_init_seed.py @@ -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