def test_get_object_metadata_err(self): tf = tempfile.NamedTemporaryFile() try: utils.get_object_metadata(os.path.join(tf.name, "doesNotEx1st")) except GlusterFileSystemOSError as e: assert e.errno != errno.ENOENT else: self.fail("Expected exception")
def test_get_object_metadata_file(self): tf = tempfile.NamedTemporaryFile() tf.file.write('123'); tf.file.flush() md = utils.get_object_metadata(tf.name) for key in self.obj_keys: assert key in md, "Expected key %s in %r" % (key, md) assert md[utils.X_TYPE] == utils.OBJECT assert md[utils.X_OBJECT_TYPE] == utils.FILE assert md[utils.X_CONTENT_TYPE] == utils.FILE_TYPE assert md[utils.X_CONTENT_LENGTH] == os.path.getsize(tf.name) assert md[utils.X_TIMESTAMP] == normalize_timestamp(os.path.getctime(tf.name)) assert md[utils.X_ETAG] == utils._get_etag(tf.name)
def test_get_object_metadata_dir(self): td = tempfile.mkdtemp() try: md = utils.get_object_metadata(td) for key in self.obj_keys: assert key in md, "Expected key %s in %r" % (key, md) assert md[utils.X_TYPE] == utils.OBJECT assert md[utils.X_OBJECT_TYPE] == utils.DIR assert md[utils.X_CONTENT_TYPE] == utils.DIR_TYPE assert md[utils.X_CONTENT_LENGTH] == 0 assert md[utils.X_TIMESTAMP] == normalize_timestamp(os.path.getctime(td)) assert md[utils.X_ETAG] == hashlib.md5().hexdigest() finally: os.rmdir(td)
def make_directory(full_path, uid, gid, metadata=None): """ Make a directory and change the owner ship as specified, and potentially creating the object metadata if requested. """ try: os.mkdir(full_path) except OSError as err: if err.errno == errno.ENOENT: # Tell the caller some directory of the parent path does not # exist. return False, metadata elif err.errno == errno.EEXIST: # Possible race, in that the caller invoked this method when it # had previously determined the file did not exist. # # FIXME: When we are confident, remove this stat() call as it is # not necessary. try: stats = os.stat(full_path) except OSError as serr: # 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 path %s already exists, and" " a subsequent os.stat on that same" " path failed (%s)" % (full_path, str(serr))) else: is_dir = stat.S_ISDIR(stats.st_mode) 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 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 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 # possible the directory now exists, stat() it to find out after a # short period of time. _random_sleep() try: stats = os.stat(full_path) except OSError as serr: if serr.errno == errno.ENOENT: errmsg = "_make_directory_unlocked: os.mkdir failed on" \ " path %s (EIO), and a subsequent os.stat on" \ " that same path did not find the file." % ( full_path,) else: errmsg = "_make_directory_unlocked: os.mkdir failed on" \ " path %s (%s), and a subsequent os.stat on" \ " that same path failed as well (%s)" % ( full_path, str(err), str(serr)) raise DiskFileError(errmsg) else: # The directory at least exists now is_dir = stat.S_ISDIR(stats.st_mode) if is_dir: # Dump the stats to the log with the original exception. logging.warn("_make_directory_unlocked: os.mkdir initially" " failed on path %s (%s) but a stat()" " following that succeeded: %r" % (full_path, str(err), stats)) # Assume another entity took care of the proper setup. return True, metadata else: raise DiskFileError("_make_directory_unlocked: os.mkdir" " initially failed on path %s (%s) but" " now we see that it exists but is not" " a directory (%r)" % (full_path, str(err), stats)) else: # Some other potentially rare exception occurred that does not # currently warrant a special log entry to help diagnose. raise DiskFileError("_make_directory_unlocked: os.mkdir failed on" " path %s (%s)" % (full_path, str(err))) else: if metadata: # We were asked to set the initial metadata for this object. metadata_orig = get_object_metadata(full_path) metadata_orig.update(metadata) write_metadata(full_path, metadata_orig) metadata = metadata_orig # We created it, so we are reponsible for always setting the proper # ownership. do_chown(full_path, uid, gid) return True, metadata
def test_get_object_metadata_dne(self): md = utils.get_object_metadata("/tmp/doesNotEx1st") assert md == {}
def make_directory(full_path, uid, gid, metadata=None): """ Make a directory and change the owner ship as specified, and potentially creating the object metadata if requested. """ try: do_mkdir(full_path) except OSError as err: if err.errno == errno.ENOENT: # Tell the caller some directory of the parent path does not # exist. return False, metadata elif err.errno == errno.EEXIST: # Possible race, in that the caller invoked this method when it # had previously determined the file did not exist. # # FIXME: When we are confident, remove this stat() call as it is # not necessary. try: stats = do_stat(full_path) except GlusterFileSystemOSError as serr: # FIXME: Ideally we'd want to return an appropriate error # message and code in the PUT Object REST API response. raise DiskFileError("make_directory: mkdir failed" " because path %s already exists, and" " a subsequent stat on that same" " path failed (%s)" % (full_path, str(serr))) else: is_dir = stat.S_ISDIR(stats.st_mode) 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 AlreadyExistsAsFile("make_directory:" " 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 AlreadyExistsAsFile("make_directory:" " 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 # possible the directory now exists, stat() it to find out after a # short period of time. _random_sleep() try: stats = do_stat(full_path) except GlusterFileSystemOSError as serr: if serr.errno == errno.ENOENT: errmsg = "make_directory: mkdir failed on" \ " path %s (EIO), and a subsequent stat on" \ " that same path did not find the file." % ( full_path,) else: errmsg = "make_directory: mkdir failed on" \ " path %s (%s), and a subsequent stat on" \ " that same path failed as well (%s)" % ( full_path, str(err), str(serr)) raise DiskFileError(errmsg) else: if not stats: errmsg = "make_directory: mkdir failed on" \ " path %s (EIO), and a subsequent stat on" \ " that same path did not find the file." % ( full_path,) raise DiskFileError(errmsg) else: # The directory at least exists now is_dir = stat.S_ISDIR(stats.st_mode) if is_dir: # Dump the stats to the log with the original exception logging.warn("make_directory: mkdir initially" " failed on path %s (%s) but a stat()" " following that succeeded: %r" % (full_path, str(err), stats)) # Assume another entity took care of the proper setup. return True, metadata else: raise DiskFileError("make_directory: mkdir" " initially failed on path %s (%s)" " but now we see that it exists" " but is not a directory (%r)" % (full_path, str(err), stats)) else: # Some other potentially rare exception occurred that does not # currently warrant a special log entry to help diagnose. raise DiskFileError("make_directory: mkdir failed on" " path %s (%s)" % (full_path, str(err))) else: if metadata: # We were asked to set the initial metadata for this object. metadata_orig = get_object_metadata(full_path) metadata_orig.update(metadata) write_metadata(full_path, metadata_orig) metadata = metadata_orig # We created it, so we are reponsible for always setting the proper # ownership. do_chown(full_path, uid, gid) return True, metadata