summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2013-05-29 11:00:42 +0000
committerGerrit Code Review <review@openstack.org>2013-05-29 11:00:42 +0000
commitb3f71fe365beb9b439017f3673a1e0356f87a19d (patch)
treea26bd9579df82af52d00212a04a8a9573dae04ca
parent34efd5db9f382e2e252ae119f8ccfbb11a52ad14 (diff)
parent68cc1cd511298208dde59878bfbef474a3625c9f (diff)
Merge "Clean up failed image transfers in instance spawn"
-rw-r--r--nova/tests/virt/powervm/test_powervm.py67
-rw-r--r--nova/virt/powervm/blockdev.py49
2 files changed, 97 insertions, 19 deletions
diff --git a/nova/tests/virt/powervm/test_powervm.py b/nova/tests/virt/powervm/test_powervm.py
index ef4ea4a43..a923d52ff 100644
--- a/nova/tests/virt/powervm/test_powervm.py
+++ b/nova/tests/virt/powervm/test_powervm.py
@@ -19,6 +19,7 @@ Test suite for PowerVMDriver.
"""
import contextlib
+import os
import paramiko
from nova import context
@@ -744,3 +745,69 @@ class PowerVMLocalVolumeAdapterTestCase(test.TestCase):
self.powervm_adapter.create_volume_from_image,
self.context, self.instance, self.image_id)
self.assertTrue(self.delete_volume_called)
+
+ def test_copy_image_file_wrong_checksum(self):
+ file_path = os.tempnam('/tmp', 'image')
+ remote_path = '/mnt/openstack/images'
+ exp_remote_path = os.path.join(remote_path,
+ os.path.basename(file_path))
+ exp_cmd = ' '.join(['/usr/bin/rm -f', exp_remote_path])
+
+ def fake_md5sum_remote_file(remote_path):
+ return '3202937169'
+
+ def fake_checksum_local_file(source_path):
+ return '3229026618'
+
+ fake_noop = lambda *args, **kwargs: None
+ fake_op = self.powervm_adapter
+ self.stubs.Set(fake_op, 'run_vios_command', fake_noop)
+ self.stubs.Set(fake_op, '_md5sum_remote_file',
+ fake_md5sum_remote_file)
+ self.stubs.Set(fake_op, '_checksum_local_file',
+ fake_checksum_local_file)
+ self.stubs.Set(common, 'ftp_put_command', fake_noop)
+
+ self.mox.StubOutWithMock(self.powervm_adapter,
+ 'run_vios_command_as_root')
+ self.powervm_adapter.run_vios_command_as_root(exp_cmd).AndReturn([])
+
+ self.mox.ReplayAll()
+
+ self.assertRaises(exception.PowerVMFileTransferFailed,
+ self.powervm_adapter._copy_image_file,
+ file_path, remote_path)
+
+ def test_checksum_local_file(self):
+ file_path = os.tempnam('/tmp', 'image')
+ img_file = file(file_path, 'w')
+ img_file.write('This is a test')
+ img_file.close()
+ exp_md5sum = 'ce114e4501d2f4e2dcea3e17b546f339'
+
+ self.assertEqual(self.powervm_adapter._checksum_local_file(file_path),
+ exp_md5sum)
+ os.remove(file_path)
+
+ def test_copy_image_file_from_host_with_wrong_checksum(self):
+ local_path = 'some/tmp'
+ remote_path = os.tempnam('/mnt/openstack/images', 'image')
+
+ def fake_md5sum_remote_file(remote_path):
+ return '3202937169'
+
+ def fake_checksum_local_file(source_path):
+ return '3229026618'
+
+ fake_noop = lambda *args, **kwargs: None
+ fake_op = self.powervm_adapter
+ self.stubs.Set(fake_op, 'run_vios_command_as_root', fake_noop)
+ self.stubs.Set(fake_op, '_md5sum_remote_file',
+ fake_md5sum_remote_file)
+ self.stubs.Set(fake_op, '_checksum_local_file',
+ fake_checksum_local_file)
+ self.stubs.Set(common, 'ftp_get_command', fake_noop)
+
+ self.assertRaises(exception.PowerVMFileTransferFailed,
+ self.powervm_adapter._copy_image_file_from_host,
+ remote_path, local_path)
diff --git a/nova/virt/powervm/blockdev.py b/nova/virt/powervm/blockdev.py
index 5e207e1f2..73099b148 100644
--- a/nova/virt/powervm/blockdev.py
+++ b/nova/virt/powervm/blockdev.py
@@ -384,6 +384,22 @@ class PowerVMLocalVolumeAdapter(PowerVMDiskAdapter):
output = self.run_vios_command_as_root(cmd)
return output[0]
+ def _checksum_local_file(self, source_path):
+ """Calculate local file checksum.
+
+ :param source_path: source file path
+ :returns: string -- the md5sum of local file
+ """
+ with open(source_path, 'r') as img_file:
+ hasher = hashlib.md5()
+ block_size = 0x10000
+ buf = img_file.read(block_size)
+ while len(buf) > 0:
+ hasher.update(buf)
+ buf = img_file.read(block_size)
+ source_cksum = hasher.hexdigest()
+ return source_cksum
+
def _copy_image_file(self, source_path, remote_path, decompress=False):
"""Copy file to VIOS, decompress it, and return its new size and name.
@@ -393,14 +409,7 @@ class PowerVMLocalVolumeAdapter(PowerVMDiskAdapter):
if False (default), just copies the file
"""
# Calculate source image checksum
- hasher = hashlib.md5()
- block_size = 0x10000
- img_file = file(source_path, 'r')
- buf = img_file.read(block_size)
- while len(buf) > 0:
- hasher.update(buf)
- buf = img_file.read(block_size)
- source_cksum = hasher.hexdigest()
+ source_cksum = self._checksum_local_file(source_path)
comp_path = os.path.join(remote_path, os.path.basename(source_path))
if comp_path.endswith(".gz"):
@@ -426,10 +435,18 @@ class PowerVMLocalVolumeAdapter(PowerVMDiskAdapter):
output = self._md5sum_remote_file(final_path)
if not output:
LOG.error(_("Unable to get checksum"))
- raise exception.PowerVMFileTransferFailed()
+ # Cleanup inconsistent remote file
+ cmd = "/usr/bin/rm -f %s" % final_path
+ self.run_vios_command_as_root(cmd)
+
+ raise exception.PowerVMFileTransferFailed(file_path=final_path)
if source_cksum != output.split(' ')[0]:
LOG.error(_("Image checksums do not match"))
- raise exception.PowerVMFileTransferFailed()
+ # Cleanup inconsistent remote file
+ cmd = "/usr/bin/rm -f %s" % final_path
+ self.run_vios_command_as_root(cmd)
+
+ raise exception.PowerVMFileTransferFailed(file_path=final_path)
if decompress:
# Unzip the image
@@ -509,19 +526,13 @@ class PowerVMLocalVolumeAdapter(PowerVMDiskAdapter):
local_file_path)
# Calculate copied image checksum
- with open(local_file_path, 'r') as image_file:
- hasher = hashlib.md5()
- block_size = 0x10000
- buf = image_file.read(block_size)
- while len(buf) > 0:
- hasher.update(buf)
- buf = image_file.read(block_size)
- dest_chksum = hasher.hexdigest()
+ dest_chksum = self._checksum_local_file(local_file_path)
# do comparison
if source_chksum and dest_chksum != source_chksum:
LOG.error(_("Image checksums do not match"))
- raise exception.PowerVMFileTransferFailed()
+ raise exception.PowerVMFileTransferFailed(
+ file_path=local_file_path)
# Cleanup transferred remote file
cmd = "/usr/bin/rm -f %s" % copy_from_path