summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gluster/swift/obj/diskfile.py34
-rw-r--r--gluster/swift/obj/server.py17
-rw-r--r--test/unit/obj/test_diskfile.py9
3 files changed, 45 insertions, 15 deletions
diff --git a/gluster/swift/obj/diskfile.py b/gluster/swift/obj/diskfile.py
index 3e4c5af..852f69f 100644
--- a/gluster/swift/obj/diskfile.py
+++ b/gluster/swift/obj/diskfile.py
@@ -29,6 +29,8 @@ from hashlib import md5
from eventlet import sleep
from greenlet import getcurrent
from contextlib import contextmanager
+from gluster.swift.common.exceptions import AlreadyExistsAsFile, \
+ AlreadyExistsAsDir
from swift.common.utils import TRUE_VALUES, ThreadPool, config_true_value
from swift.common.exceptions import DiskFileNotExist, DiskFileError, \
DiskFileNoSpace, DiskFileDeviceUnavailable, DiskFileNotOpen
@@ -166,17 +168,19 @@ def _make_directory_unlocked(full_path, uid, gid, metadata=None):
if not is_dir:
# FIXME: Ideally we'd want to return an appropriate error
# message and code in the PUT Object REST API response.
- raise DiskFileError("_make_directory_unlocked: os.mkdir"
- " failed on path %s because it already"
- " exists but not as a directory" % (
- full_path))
+ raise AlreadyExistsAsFile("_make_directory_unlocked:"
+ " os.mkdir failed on path %s"
+ " because it already exists"
+ " but not as a directory"
+ % (full_path))
return True, metadata
elif err.errno == errno.ENOTDIR:
# FIXME: Ideally we'd want to return an appropriate error
# message and code in the PUT Object REST API response.
- raise DiskFileError("_make_directory_unlocked: os.mkdir failed"
- " because some part of path %s is not in fact"
- " a directory" % (full_path))
+ raise AlreadyExistsAsFile("_make_directory_unlocked:"
+ " os.mkdir failed because some "
+ "part of path %s is not in fact"
+ " a directory" % (full_path))
elif err.errno == errno.EIO:
# Sometimes Fuse will return an EIO error when it does not know
# how to handle an unexpected, but transient situation. It is
@@ -482,6 +486,8 @@ class DiskFileWriter(object):
written to the temp file.
:param metadata: dictionary of metadata to be written
+ :raises AlreadyExistsAsDir : If there exists a directory of the same
+ name
"""
assert self._tmppath is not None
metadata = _adjust_metadata(metadata)
@@ -497,9 +503,9 @@ class DiskFileWriter(object):
# system, perhaps gratuitously created when another
# object was created, or created externally to Swift
# REST API servicing (UFO use case).
- raise DiskFileError('DiskFile.put(): file creation failed since'
- ' the target, %s, already exists as a'
- ' directory' % df._data_file)
+ raise AlreadyExistsAsDir('DiskFile.put(): file creation failed'
+ ' since the target, %s, already exists'
+ ' as a directory' % df._data_file)
df._threadpool.force_run_in_thread(self._finalize_put, metadata)
@@ -897,6 +903,8 @@ class DiskFile(object):
:param size: optional initial size of file to explicitly allocate on
disk
:raises DiskFileNoSpace: if a size is specified and allocation fails
+ :raises AlreadyExistsAsFile: if path or part of a path is not a \
+ directory
"""
data_file = os.path.join(self._put_datadir, self._obj)
@@ -917,6 +925,12 @@ class DiskFile(object):
# Raise DiskFileNoSpace to be handled by upper layers when
# there is no space on disk OR when quota is exceeded
raise DiskFileNoSpace()
+ if gerr.errno == errno.ENOTDIR:
+ raise AlreadyExistsAsFile('do_open(): failed on %s,'
+ ' path or part of a'
+ ' path is not a directory'
+ % (tmppath))
+
if gerr.errno not in (errno.ENOENT, errno.EEXIST, errno.EIO):
# FIXME: Other cases we should handle?
raise
diff --git a/gluster/swift/obj/server.py b/gluster/swift/obj/server.py
index 6417475..3cdd3c0 100644
--- a/gluster/swift/obj/server.py
+++ b/gluster/swift/obj/server.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2012-2013 Red Hat, Inc.
+# Copyright (c) 2012-2014 Red Hat, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -18,6 +18,11 @@
# Simply importing this monkey patches the constraint handling to fit our
# needs
import gluster.swift.common.constraints # noqa
+from swift.common.swob import HTTPConflict
+from swift.common.utils import public, timing_stats
+from gluster.swift.common.exceptions import AlreadyExistsAsFile, \
+ AlreadyExistsAsDir
+from swift.common.request_helpers import split_and_validate_path
from swift.obj import server
@@ -80,6 +85,16 @@ class ObjectController(server.ObjectController):
"""
return
+ @public
+ @timing_stats()
+ def PUT(self, request):
+ try:
+ return server.ObjectController.PUT(self, request)
+ except (AlreadyExistsAsFile, AlreadyExistsAsDir):
+ device = \
+ split_and_validate_path(request, 1, 5, True)
+ return HTTPConflict(drive=device, request=request)
+
def app_factory(global_conf, **local_conf):
"""paste.deploy app factory for creating WSGI object server apps"""
diff --git a/test/unit/obj/test_diskfile.py b/test/unit/obj/test_diskfile.py
index a767261..64fa6e7 100644
--- a/test/unit/obj/test_diskfile.py
+++ b/test/unit/obj/test_diskfile.py
@@ -26,7 +26,8 @@ from eventlet import tpool
from mock import Mock, patch
from hashlib import md5
from copy import deepcopy
-
+from gluster.swift.common.exceptions import AlreadyExistsAsDir, \
+ AlreadyExistsAsFile
from swift.common.exceptions import DiskFileNotExist, DiskFileError, \
DiskFileNoSpace, DiskFileNotOpen
from swift.common.utils import ThreadPool
@@ -409,7 +410,7 @@ class TestDiskFile(unittest.TestCase):
dc = gluster.swift.obj.diskfile.do_chown
gluster.swift.obj.diskfile.do_chown = _mock_do_chown
self.assertRaises(
- DiskFileError, gdf._create_dir_object, the_dir)
+ AlreadyExistsAsFile, gdf._create_dir_object, the_dir)
gluster.swift.obj.diskfile.do_chown = dc
self.assertFalse(os.path.isdir(the_dir))
self.assertFalse(_mapit(the_dir) in _metadata)
@@ -431,7 +432,7 @@ class TestDiskFile(unittest.TestCase):
dc = gluster.swift.obj.diskfile.do_chown
gluster.swift.obj.diskfile.do_chown = _mock_do_chown
self.assertRaises(
- DiskFileError, gdf._create_dir_object, the_dir)
+ AlreadyExistsAsFile, gdf._create_dir_object, the_dir)
gluster.swift.obj.diskfile.do_chown = dc
self.assertFalse(os.path.isdir(the_dir))
self.assertFalse(_mapit(the_dir) in _metadata)
@@ -622,7 +623,7 @@ class TestDiskFile(unittest.TestCase):
# directory.
dw.write('12345\n')
dw.put(newmd)
- except DiskFileError:
+ except AlreadyExistsAsDir:
pass
else:
self.fail("Expected to encounter"