Fix quarantine when object path is not a directory

In the diskfile module, there are a couple of cases where we would
quarantine the suffix dir if a single object within is not a directory.

Change the code so that we quarantine only the object.

Change-Id: I35eb16f568c00d973eb089aedd0e5a5619c25a2f
This commit is contained in:
Alexandre Lécuyer 2019-04-18 16:35:07 +02:00 committed by John Dickinson
parent aa4bc848c1
commit 6008b0a83f
2 changed files with 18 additions and 4 deletions

View File

@ -1132,7 +1132,14 @@ class BaseDiskFileManager(object):
partition_path = dirname(path) partition_path = dirname(path)
objects_path = dirname(partition_path) objects_path = dirname(partition_path)
device_path = dirname(objects_path) device_path = dirname(objects_path)
quar_path = quarantine_renamer(device_path, hsh_path) # The made-up filename is so that the eventual dirpath()
# will result in this object directory that we care about.
# Some failures will result in an object directory
# becoming a file, thus causing the parent directory to
# be qarantined.
quar_path = quarantine_renamer(device_path,
join(hsh_path,
"made-up-filename"))
logging.exception( logging.exception(
_('Quarantined %(hsh_path)s to %(quar_path)s because ' _('Quarantined %(hsh_path)s to %(quar_path)s because '
'it is not a directory'), {'hsh_path': hsh_path, 'it is not a directory'), {'hsh_path': hsh_path,
@ -1447,7 +1454,14 @@ class BaseDiskFileManager(object):
filenames = self.cleanup_ondisk_files(object_path)['files'] filenames = self.cleanup_ondisk_files(object_path)['files']
except OSError as err: except OSError as err:
if err.errno == errno.ENOTDIR: if err.errno == errno.ENOTDIR:
quar_path = self.quarantine_renamer(dev_path, object_path) # The made-up filename is so that the eventual dirpath()
# will result in this object directory that we care about.
# Some failures will result in an object directory
# becoming a file, thus causing the parent directory to
# be qarantined.
quar_path = self.quarantine_renamer(dev_path,
join(object_path,
"made-up-filename"))
logging.exception( logging.exception(
_('Quarantined %(object_path)s to %(quar_path)s because ' _('Quarantined %(object_path)s to %(quar_path)s because '
'it is not a directory'), {'object_path': object_path, 'it is not a directory'), {'object_path': object_path,

View File

@ -1217,7 +1217,8 @@ class DiskFileManagerMixin(BaseDiskFileTestMixin):
'dev', '9', '9a7175077c01a23ade5956b8a2bba900', POLICIES[0]) 'dev', '9', '9a7175077c01a23ade5956b8a2bba900', POLICIES[0])
quarantine_renamer.assert_called_once_with( quarantine_renamer.assert_called_once_with(
'/srv/dev/', '/srv/dev/',
'/srv/dev/objects/9/900/9a7175077c01a23ade5956b8a2bba900') ('/srv/dev/objects/9/900/9a7175077c01a23ade5956b8a2bba900/' +
'made-up-filename'))
def test_get_diskfile_from_hash_no_dir(self): def test_get_diskfile_from_hash_no_dir(self):
self.df_mgr.get_dev_path = mock.MagicMock(return_value='/srv/dev/') self.df_mgr.get_dev_path = mock.MagicMock(return_value='/srv/dev/')
@ -7707,7 +7708,6 @@ class TestSuffixHashes(unittest.TestCase):
quarantine_path = os.path.join( quarantine_path = os.path.join(
quarantine_base, # quarantine root quarantine_base, # quarantine root
diskfile.get_data_dir(policy), # per-policy data dir diskfile.get_data_dir(policy), # per-policy data dir
suffix, # first dir from which quarantined file was removed
os.path.basename(df._datadir) # name of quarantined file os.path.basename(df._datadir) # name of quarantined file
) )
self.assertTrue(os.path.exists(quarantine_path)) self.assertTrue(os.path.exists(quarantine_path))