diff options
author | Pavel Kirpichyov <pavel.kirpichyov@gmail.com> | 2014-04-07 13:36:38 +0300 |
---|---|---|
committer | Pavel Kirpichyov <pavel.kirpichyov@gmail.com> | 2014-04-08 20:23:49 +0300 |
commit | 56d53db1d6178fca4586efa3c0d72916d79e7220 (patch) | |
tree | c33c81fa7549d1be6425e2e4903606dc8d44ed81 /nova | |
parent | 4a7ce4a1e3bb6e9b688123b3ab920f9a9d2fff5a (diff) | |
download | nova-56d53db1d6178fca4586efa3c0d72916d79e7220.tar.gz |
Check image exists before calling inject_data
os.stat removal is needed for network-based image backends
Partly revert Change-Id: I264540de736c2bcb92567826fe5ba672e1244ba2
Partly fixes bug #1257674
Change-Id: I83e95fec6f08bc36f0e2b299fb269ceaa3500243
Diffstat (limited to 'nova')
-rw-r--r-- | nova/tests/fakeguestfs.py | 3 | ||||
-rw-r--r-- | nova/tests/virt/baremetal/test_pxe.py | 3 | ||||
-rw-r--r-- | nova/tests/virt/baremetal/test_tilera.py | 5 | ||||
-rw-r--r-- | nova/tests/virt/libvirt/test_libvirt.py | 24 | ||||
-rw-r--r-- | nova/tests/virt/test_virt_disk.py | 19 | ||||
-rw-r--r-- | nova/virt/baremetal/utils.py | 12 | ||||
-rw-r--r-- | nova/virt/disk/api.py | 6 | ||||
-rw-r--r-- | nova/virt/libvirt/driver.py | 19 |
8 files changed, 57 insertions, 34 deletions
diff --git a/nova/tests/fakeguestfs.py b/nova/tests/fakeguestfs.py index 0d29cb34ca..c8424282d5 100644 --- a/nova/tests/fakeguestfs.py +++ b/nova/tests/fakeguestfs.py @@ -40,6 +40,9 @@ class GuestFS(object): self.closed = True def add_drive_opts(self, file, *args, **kwargs): + if file == "/some/fail/file": + raise RuntimeError("%s: No such file or directory", file) + self.drives.append((file, kwargs['format'])) def inspect_os(self): diff --git a/nova/tests/virt/baremetal/test_pxe.py b/nova/tests/virt/baremetal/test_pxe.py index 674a007efd..6787983014 100644 --- a/nova/tests/virt/baremetal/test_pxe.py +++ b/nova/tests/virt/baremetal/test_pxe.py @@ -414,6 +414,9 @@ class PXEPrivateMethodsTestCase(BareMetalPXETestCase): net = pxe.build_network_config(net_info) admin_password = 'fake password' + self.mox.StubOutWithMock(os.path, 'exists') + os.path.exists(mox.IgnoreArg()).AndReturn(True) + self.mox.StubOutWithMock(disk_api, 'inject_data') disk_api.inject_data( admin_password=admin_password, diff --git a/nova/tests/virt/baremetal/test_tilera.py b/nova/tests/virt/baremetal/test_tilera.py index 0c405452d0..8c1ff40947 100644 --- a/nova/tests/virt/baremetal/test_tilera.py +++ b/nova/tests/virt/baremetal/test_tilera.py @@ -19,6 +19,8 @@ import os +import mox + from oslo.config import cfg from nova import exception @@ -243,6 +245,9 @@ class TileraPrivateMethodsTestCase(BareMetalTileraTestCase): net = tilera.build_network_config(net_info) admin_password = 'fake password' + self.mox.StubOutWithMock(os.path, 'exists') + os.path.exists(mox.IgnoreArg()).AndReturn(True) + self.mox.StubOutWithMock(disk_api, 'inject_data') disk_api.inject_data( admin_password=admin_password, diff --git a/nova/tests/virt/libvirt/test_libvirt.py b/nova/tests/virt/libvirt/test_libvirt.py index 500863c138..faaddc21fe 100644 --- a/nova/tests/virt/libvirt/test_libvirt.py +++ b/nova/tests/virt/libvirt/test_libvirt.py @@ -8525,17 +8525,25 @@ class LibvirtDriverTestCase(test.TestCase): called=True): conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI()) - class i(object): + class ImageBackend(object): path = '/path' + def check_image_exists(self): + if self.path == '/fail/path': + return False + return True + def fake_inj_network(*args, **kwds): return args[0] or None inj_network.side_effect = fake_inj_network + image_backend = ImageBackend() + image_backend.path = disk_params[0] + with mock.patch.object( conn.image_backend, 'image', - return_value=i()): + return_value=image_backend): self.flags(inject_partition=0, group='libvirt') conn._inject_data(**driver_params) @@ -8639,6 +8647,18 @@ class LibvirtDriverTestCase(test.TestCase): ] self._test_inject_data(driver_params, disk_params) + def test_inject_not_exist_image(self): + driver_params = self._test_inject_data_default_driver_params() + disk_params = [ + '/fail/path', # injection_path + 'key-content', # key + None, # net + None, # metadata + None, # admin_pass + None, # files + ] + self._test_inject_data(driver_params, disk_params, called=False) + class LibvirtVolumeUsageTestCase(test.TestCase): """Test for LibvirtDriver.get_all_volume_usage.""" diff --git a/nova/tests/virt/test_virt_disk.py b/nova/tests/virt/test_virt_disk.py index a0f4dcc364..fe886293fb 100644 --- a/nova/tests/virt/test_virt_disk.py +++ b/nova/tests/virt/test_virt_disk.py @@ -12,12 +12,9 @@ # License for the specific language governing permissions and limitations # under the License. -import fixtures import os import sys -import posix - from nova import exception from nova import test from nova.tests import fakeguestfs @@ -34,19 +31,6 @@ class VirtDiskTest(test.NoDBTestCase): def test_inject_data(self): - orig_os_stat = os.stat - - def fake_stat(arg): - if arg == '/some/file': # fake success - return posix.stat_result((16877, 2, 2049L, - 23, 0, 0, - 4096, 1381787843, - 1381635971, 1381635971)) - else: - return orig_os_stat(arg) - - self.useFixture(fixtures.MonkeyPatch('os.stat', fake_stat)) - self.assertTrue(diskapi.inject_data("/some/file", use_cow=True)) self.assertTrue(diskapi.inject_data("/some/file", @@ -64,7 +48,8 @@ class VirtDiskTest(test.NoDBTestCase): self.assertFalse(diskapi.inject_data("/some/file", admin_password="p")) os.name = os_name - self.assertFalse(diskapi.inject_data("/some/fail/file")) + self.assertFalse(diskapi.inject_data("/some/fail/file", + key="mysshkey")) def test_inject_data_key(self): diff --git a/nova/virt/baremetal/utils.py b/nova/virt/baremetal/utils.py index 59223a611c..c54d3c14dd 100644 --- a/nova/virt/baremetal/utils.py +++ b/nova/virt/baremetal/utils.py @@ -34,11 +34,15 @@ def cache_image(context, target, image_id, user_id, project_id, clean=False): user_id, project_id) -def inject_into_image(image, key, net, metadata, admin_password, - files, partition, use_cow=False): +def inject_into_image(image, key, net, metadata, admin_password, files, + partition, use_cow=False): try: - disk_api.inject_data(image, key, net, metadata, admin_password, - files, partition, use_cow) + if os.path.exists(image): + disk_api.inject_data(image, key, net, metadata, admin_password, + files, partition, use_cow) + else: + LOG.warning(_('Image %s not found on disk storage. ' + 'Continue without injecting data'), image) except Exception as e: LOG.warn(_("Failed to inject data into image %(image)s. " "Error: %(e)s"), {'image': image, 'e': e}) diff --git a/nova/virt/disk/api.py b/nova/virt/disk/api.py index e603ce4843..b78d359caf 100644 --- a/nova/virt/disk/api.py +++ b/nova/virt/disk/api.py @@ -347,8 +347,6 @@ def inject_data(image, key=None, net=None, metadata=None, admin_password=None, if use_cow: fmt = "qcow2" try: - # Note(mrda): Test if the image exists first to short circuit errors - os.stat(image) fs = vfs.VFS.instance_for_image(image, fmt, partition) fs.setup() except Exception as e: @@ -363,8 +361,8 @@ def inject_data(image, key=None, net=None, metadata=None, admin_password=None, return False try: - return inject_data_into_fs(fs, key, net, metadata, - admin_password, files, mandatory) + return inject_data_into_fs(fs, key, net, metadata, admin_password, + files, mandatory) finally: fs.teardown() diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index e6837e2050..940d5da767 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -2518,18 +2518,23 @@ class LibvirtDriver(driver.ComputeDriver): image_type = CONF.libvirt.images_type if any((key, net, metadata, admin_pass, files)): - injection_path = self.image_backend.image( + injection_image = self.image_backend.image( instance, 'disk' + suffix, - image_type).path + image_type) img_id = instance['image_ref'] try: - disk.inject_data(injection_path, - key, net, metadata, admin_pass, files, - partition=target_partition, - use_cow=CONF.use_cow_images, - mandatory=('files',)) + if injection_image.check_image_exists(): + disk.inject_data(injection_image.path, + key, net, metadata, admin_pass, files, + partition=target_partition, + use_cow=CONF.use_cow_images, + mandatory=('files',)) + else: + LOG.warning(_('Image %s not found on disk storage. ' + 'Continue without injecting data'), + injection_image.path, instance=instance) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error(_('Error injecting data into image ' |