diff options
author | Zuul <zuul@review.openstack.org> | 2018-11-27 18:47:59 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2018-11-27 18:47:59 +0000 |
commit | 612a94eb63e8e8e7919e3d8dc4b2b7c561f31bcf (patch) | |
tree | 431ffe4cb23ebbd0b3c79c64545d1556f5fad3d7 | |
parent | 55c99b963070c80d491da7148bfcdb844aacaf44 (diff) | |
parent | 4573cfba6532e5f6231e28505f807563d78fee1d (diff) | |
download | ironic-612a94eb63e8e8e7919e3d8dc4b2b7c561f31bcf.tar.gz |
Merge "Improve logs when hard linking images fails" into stable/queens
-rw-r--r-- | ironic/drivers/modules/image_cache.py | 11 | ||||
-rw-r--r-- | ironic/tests/unit/drivers/modules/test_image_cache.py | 12 | ||||
-rw-r--r-- | releasenotes/notes/invalid_cross_device_link-7ecf3543a8ada09f.yaml | 5 |
3 files changed, 28 insertions, 0 deletions
diff --git a/ironic/drivers/modules/image_cache.py b/ironic/drivers/modules/image_cache.py index 0b3133c8f..5d4a166d9 100644 --- a/ironic/drivers/modules/image_cache.py +++ b/ironic/drivers/modules/image_cache.py @@ -30,6 +30,7 @@ import six from ironic.common import exception from ironic.common.glance_service import service_utils +from ironic.common.i18n import _ from ironic.common import image_service from ironic.common import images from ironic.common import utils @@ -148,6 +149,9 @@ class ImageCache(object): :param ctx: context :param force_raw: boolean value, whether to convert the image to raw format + :raise ImageDownloadFailed: when the image cache and the image HTTP or + TFTP location are on different file system, + causing hard link to fail. """ # TODO(ghe): timeout and retry for downloads # TODO(ghe): logging when image cannot be created @@ -160,6 +164,13 @@ class ImageCache(object): # will have link count >1 at any moment, so won't be cleaned up os.link(tmp_path, master_path) os.link(master_path, dest_path) + except OSError as exc: + msg = (_("Could not link image %(img_href)s from %(src_path)s " + "to %(dst_path)s, error: %(exc)s") % + {'img_href': href, 'src_path': master_path, + 'dst_path': dest_path, 'exc': exc}) + LOG.error(msg) + raise exception.ImageDownloadFailed(msg) finally: utils.rmtree_without_raise(tmp_dir) diff --git a/ironic/tests/unit/drivers/modules/test_image_cache.py b/ironic/tests/unit/drivers/modules/test_image_cache.py index b50d3fe40..5bd4c8d33 100644 --- a/ironic/tests/unit/drivers/modules/test_image_cache.py +++ b/ironic/tests/unit/drivers/modules/test_image_cache.py @@ -174,6 +174,18 @@ class TestImageCacheFetch(base.TestCase): with open(self.dest_path) as fp: self.assertEqual("TEST", fp.read()) + @mock.patch.object(image_cache, '_fetch', autospec=True) + @mock.patch.object(image_cache, 'LOG', autospec=True) + @mock.patch.object(os, 'link', autospec=True) + def test__download_image_linkfail(self, mock_link, mock_log, mock_fetch): + mock_link.side_effect = [None, OSError] + self.assertRaises(exception.ImageDownloadFailed, + self.cache._download_image, + self.uuid, self.master_path, self.dest_path) + self.assertTrue(mock_fetch.called) + self.assertEqual(2, mock_link.call_count) + self.assertTrue(mock_log.error.called) + @mock.patch.object(os, 'unlink', autospec=True) class TestUpdateImages(base.TestCase): diff --git a/releasenotes/notes/invalid_cross_device_link-7ecf3543a8ada09f.yaml b/releasenotes/notes/invalid_cross_device_link-7ecf3543a8ada09f.yaml new file mode 100644 index 000000000..d9e4cebbe --- /dev/null +++ b/releasenotes/notes/invalid_cross_device_link-7ecf3543a8ada09f.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Properly reports an error when the image cache and the image HTTP or TFTP + location are on different file system, causing hard link to fail. |