diff options
| author | Jenkins <jenkins@review.openstack.org> | 2013-05-29 11:00:42 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2013-05-29 11:00:42 +0000 |
| commit | b3f71fe365beb9b439017f3673a1e0356f87a19d (patch) | |
| tree | a26bd9579df82af52d00212a04a8a9573dae04ca | |
| parent | 34efd5db9f382e2e252ae119f8ccfbb11a52ad14 (diff) | |
| parent | 68cc1cd511298208dde59878bfbef474a3625c9f (diff) | |
Merge "Clean up failed image transfers in instance spawn"
| -rw-r--r-- | nova/tests/virt/powervm/test_powervm.py | 67 | ||||
| -rw-r--r-- | nova/virt/powervm/blockdev.py | 49 |
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 |
