From 1d2356c8642f61bfa05226110a18cafcef55c6f0 Mon Sep 17 00:00:00 2001 From: Eoghan Glynn Date: Thu, 16 Feb 2012 18:26:38 +0000 Subject: [PATCH] Ensure StorageFull only raised on space starvation Additional fix for lp 919255 Limit StorageFull to cases of genuine disk space starvation (ENOSPC or EFBIG), in order to avoid confusion with 413 "Request entity too large" status being returned from POST /images for issues unrelated to space. Change-Id: Ib5e68e5d988d0f541803ffb3f37ddf88ac24e9dc --- glance/store/filesystem.py | 9 ++++-- glance/tests/unit/test_filesystem_store.py | 34 +++++++++++++++++----- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/glance/store/filesystem.py b/glance/store/filesystem.py index a701b612..7f9d15f2 100644 --- a/glance/store/filesystem.py +++ b/glance/store/filesystem.py @@ -19,6 +19,7 @@ A simple filesystem-backed store """ +import errno import hashlib import logging import os @@ -204,8 +205,12 @@ class Store(glance.store.base.Store): bytes_written += len(buf) checksum.update(buf) f.write(buf) - except IOError: - raise exception.StorageFull() + except IOError as e: + if e.errno in [errno.EFBIG, errno.ENOSPC]: + raise exception.StorageFull() + else: + raise + checksum_hex = checksum.hexdigest() logger.debug(_("Wrote %(bytes_written)d bytes to %(filepath)s with " diff --git a/glance/tests/unit/test_filesystem_store.py b/glance/tests/unit/test_filesystem_store.py index afa452f9..6b310e70 100644 --- a/glance/tests/unit/test_filesystem_store.py +++ b/glance/tests/unit/test_filesystem_store.py @@ -17,6 +17,7 @@ """Tests the filesystem backend store""" +import errno import StringIO import hashlib import unittest @@ -134,11 +135,7 @@ class TestStore(base.IsolatedUnitTest): self.store.add, image_id, image_file, 0) - def test_add_storage_full(self): - """ - Tests that adding an image without enough space on disk - raises an appropriate exception - """ + def _do_test_add_failure(self, errno, exception): ChunkedFile.CHUNKSIZE = 1024 image_id = utils.generate_uuid() file_size = 1024 * 5 # 5K @@ -147,13 +144,36 @@ class TestStore(base.IsolatedUnitTest): image_file = StringIO.StringIO(file_contents) def fake_IO_Error(size): - raise IOError + e = IOError() + e.errno = errno + raise e self.stubs.Set(image_file, 'read', fake_IO_Error) - self.assertRaises(exception.StorageFull, + self.assertRaises(exception, self.store.add, image_id, image_file, 0) + def test_add_storage_full(self): + """ + Tests that adding an image without enough space on disk + raises an appropriate exception + """ + self._do_test_add_failure(errno.ENOSPC, exception.StorageFull) + + def test_add_file_too_big(self): + """ + Tests that adding an excessively large image file + raises an appropriate exception + """ + self._do_test_add_failure(errno.EFBIG, exception.StorageFull) + + def test_add_other_failure(self): + """ + Tests that a non-space-related IOError does not raise a + StorageFull exception. + """ + self._do_test_add_failure(errno.ENOTDIR, IOError) + def test_delete(self): """ Test we can delete an existing image in the filesystem store