def test_chown_file_err(self):
     try:
         fs.do_chown(os.path.join('/tmp', str(random.random())),
                     20000, 20000)
     except GlusterFileSystemOSError:
         pass
     else:
         self.fail("Expected GlusterFileSystemOSError")
예제 #2
0
 def _create_dir_object(self, dir_path):
     #TODO: if object already exists???
     if os_path.exists(dir_path) and not os_path.isdir(dir_path):
         self.logger.error("Deleting file %s", dir_path)
         do_unlink(dir_path)
     #If dir aleady exist just override metadata.
     mkdirs(dir_path)
     do_chown(dir_path, self.uid, self.gid)
     create_object_metadata(dir_path)
예제 #3
0
 def initialize(self, timestamp):
     """
     Create and write metatdata to directory/container.
     :param metadata: Metadata to write.
     """
     if not self._dir_exists:
         mkdirs(self.datadir)
         # If we create it, ensure we own it.
         do_chown(self.datadir, self.uid, self.gid)
     metadata = get_container_metadata(self.datadir)
     metadata[X_TIMESTAMP] = timestamp
     write_metadata(self.datadir, metadata)
     self.metadata = metadata
     self._dir_exists = True
예제 #4
0
 def initialize(self, timestamp):
     """
     Create and write metatdata to directory/container.
     :param metadata: Metadata to write.
     """
     if not self._dir_exists:
         mkdirs(self.datadir)
         # If we create it, ensure we own it.
         do_chown(self.datadir, self.uid, self.gid)
     metadata = get_container_metadata(self.datadir)
     metadata[X_TIMESTAMP] = timestamp
     write_metadata(self.datadir, metadata)
     self.metadata = metadata
     self._dir_exists = True
예제 #5
0
    def put(self, fd, metadata, extension='.data'):
        """
        Finalize writing the file on disk, and renames it from the temp file
        to the real location.  This should be called after the data has been
        written to the temp file.

        :param fd: file descriptor of the temp file
        :param metadata: dictionary of metadata to be written
        :param extension: extension to be used when making the file
        """
        # Our caller will use '.data' here; we just ignore it since we map the
        # URL directly to the file system.

        metadata = _adjust_metadata(metadata)

        if metadata[X_OBJECT_TYPE] == MARKER_DIR:
            if not self.data_file:
                self.data_file = os.path.join(self.datadir, self._obj)
                self._create_dir_object(self.data_file)
            self.put_metadata(metadata)
            return

        # Check if directory already exists.
        if self._is_dir:
            # FIXME: How can we have a directory and it not be marked as a
            # MARKER_DIR (see above)?
            msg = 'File object exists as a directory: %s' % self.data_file
            raise AlreadyExistsAsDir(msg)

        write_metadata(self.tmppath, metadata)
        if X_CONTENT_LENGTH in metadata:
            self.drop_cache(fd, 0, int(metadata[X_CONTENT_LENGTH]))
        do_fsync(fd)
        if self._obj_path:
            dir_objs = self._obj_path.split('/')
            assert len(dir_objs) >= 1
            tmp_path = self._container_path
            for dir_name in dir_objs:
                tmp_path = os.path.join(tmp_path, dir_name)
                self._create_dir_object(tmp_path)

        newpath = os.path.join(self.datadir, self._obj)
        renamer(self.tmppath, newpath)
        do_chown(newpath, self.uid, self.gid)
        self.metadata = metadata
        self.data_file = newpath
        self.filter_metadata()
        return
예제 #6
0
 def test_chown_dir(self):
     tmpdir = mkdtemp()
     try:
         subdir = mkdtemp(dir=tmpdir)
         buf = os.stat(subdir)
         if buf.st_uid == 0:
             raise SkipTest
         else:
             try:
                 fs.do_chown(subdir, 20000, 20000)
             except OSError as ex:
                 if ex.errno != errno.EPERM:
                     self.fail("Expected OSError")
             else:
                     self.fail("Expected OSError")
     finally:
         shutil.rmtree(tmpdir)
예제 #7
0
 def test_chown_file(self):
     tmpdir = mkdtemp()
     try:
         fd, tmpfile = mkstemp(dir=tmpdir)
         buf = os.stat(tmpfile)
         if buf.st_uid == 0:
             raise SkipTest
         else:
             try:
                 fs.do_chown(tmpfile, 20000, 20000)
             except OSError as ex:
                 if ex.errno != errno.EPERM:
                     self.fail("Expected OSError")
             else:
                     self.fail("Expected OSError")
     finally:
         os.close(fd)
         shutil.rmtree(tmpdir)
예제 #8
0
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
예제 #9
0
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