Esempio n. 1
0
    def open(self, path, flags):
        full_path = self._full_path(path)
        logger.debug('open %s - flags: %s' % (path, flags))

        # when we're reading from RIAK, we're going to retrieve the file contents from RIAK and store it locally for temporary use
        if (use_riak_file_contents_for_read_access):
            RiakBucketNamespace = NameMapping.legacyPathToRiakBucketName(
                riak_namespace_prefix, path)
            RiakKeyNamespace = NameMapping.legacyPathToRiakKeyName(path)

            if RiakKeyNamespace is None:
                # apparently this is not a proper path, so just go ahead and unlink the local file and report on that
                logger.warning('%s is not a mappable RIAK bucket - ignoring.' %
                               (path))
                # so do the local rename anways...
                return os.open(full_path, flags)
            try:
                logger.debug(
                    'Retrieving key contents and storing temporarily...%s/%s' %
                    (RiakBucketNamespace, RiakKeyNamespace))
                # create RiakClient instance
                riakClient = riak.RiakClient(host=riak_host,
                                             pb_port=riak_port,
                                             protocol='pbc')
                # get the correct bucket
                bucket = riakClient.bucket(RiakBucketNamespace)
                # read the old key contents...
                the_imge_data = bucket.get(RiakKeyNamespace)
                # You've now got a ``RiakObject``. To get at the binary data, call:
                with open(full_path, 'wb') as f:
                    binary_data = the_imge_data.encoded_data
                    f.write(binary_data)
            except Exception as e:
                # throw controlled exception but do not remove the actual local file due to errors in the process...
                logger.error(
                    'ERROR retrieving data from RIAK bucket %s the key %s (Exception: %s)'
                    % (RiakBucketNamespace, RiakKeyNamespace, str(e)))
                raise FuseOSError(errno.EACCES)
            else:
                logger.debug(
                    'DONE Got the old key contents from RIAK (%s/%s) and stored temporarily %s'
                    % (RiakBucketNamespace, RiakKeyNamespace, full_path))
        return os.open(full_path, flags)
Esempio n. 2
0
    def readdir(self, path, fh):
        full_path = self._full_path(path)
        logger.debug('readdir %s - fh: %s' % (path, fh))
        dirents = ['.', '..']
        # generate the correct names for the buckets and keys
        RiakDirectoryBucketNamespace = NameMapping.legacyPathToRiakBucketName(
            riak_directory_namespace_prefix, path)

        if (use_riak_directory_structure_for_read_access) and (
                RiakDirectoryBucketNamespace is not None):
            try:
                logger.debug('using RIAK directory structure in %s (for %s)' %
                             (RiakDirectoryBucketNamespace, path))
                # Updating the $prefix+$id+$directoryprefix set with the given information
                # we shall use our own riak client instance for this
                btype = riak.RiakClient(
                    host=riak_host, pb_port=riak_port,
                    protocol='pbc').bucket_type(riak_directory_set_buckettype)
                # get the bucket for the directory namespace - this is a sets pre-configured bucket
                bucket = btype.bucket(RiakDirectoryBucketNamespace)
                # get the correct key inside that bucket
                myset = datatypes.Set(bucket, riak_directory_set_directorykey)
                # fetch the directory in order to be able to output it...
                myset.reload()
                for r in dirents:
                    yield r

                for id in myset:
                    yield id
            except Exception as e:
                # throw controlled exception
                logger.error(
                    'ERROR retrieving directory structure on RIAK bucket %s (Exception: %s)'
                    % (RiakDirectoryBucketNamespace, str(e)))
                raise FuseOSError(errno.EACCES)
        else:
            # this is not a valid namespace - so pattern did not match on a directory/filename structure known to be mapped
            # --> therefore this method will return to the caller now.
            if RiakDirectoryBucketNamespace is None:
                # apparently this is not a proper path, so just go ahead and unlink the local file and report on that
                logger.warning('%s is not a mappable RIAK bucket - ignoring.' %
                               (path))

            # take local information instead
            if os.path.isdir(full_path):
                dirents.extend(os.listdir(full_path))
            for r in dirents:
                yield r
Esempio n. 3
0
    def readlink(self, path):
        logger.debug('readlink %s' % (path))
        RiakBucketNamespace = NameMapping.legacyPathToRiakBucketName(
            riak_namespace_prefix, path)

        if RiakBucketNamespace is None:
            logger.debug(
                '%s is not a mappable RIAK bucket - therefore readlink is supported '
                % (path))
            pathname = os.readlink(self._full_path(path))
            logger.debug('Readlink Path %s' % (pathname))
            if pathname.startswith("/"):
                # Path name is absolute, sanitize it.
                return pathname
                #os.path.relpath(pathname, self.root)
            else:
                return pathname
        else:
            logger.warning('readlink is not supported on RIAK usage %s' %
                           (path))
            raise FuseOSError(errno.ENOTSUP)
Esempio n. 4
0
    def getattr(self, path, fh=None):
        full_path = self._full_path(path)
        logger.debug('getattr %s' % (path))
        if (use_riak_file_contents_for_read_access):
            RiakDirectoryBucketNamespace = NameMapping.legacyPathToRiakBucketName(
                riak_directory_namespace_prefix, path)
            RiakKeyNamespace = NameMapping.legacyPathToRiakKeyName(path)
            if RiakKeyNamespace is None:
                # apparently this is not a proper path, so just go ahead and unlink the local file and report on that
                logger.warning('%s is not a mappable RIAK bucket - ignoring.' %
                               (path))
                # so ignore...
                st = os.lstat(full_path)
            else:
                # we got a valid path, now just return the default file mask
                #st = os.lstat('/etc/passwd')
                #check if it is existing by trying to get it's size from the value stored under the file key in the directory bucket
                logger.debug(
                    'Retrieving stored object size and status...%s/%s' %
                    (RiakDirectoryBucketNamespace, RiakKeyNamespace))
                # read the set contents...
                btype = riak.RiakClient(host=riak_host,
                                        pb_port=riak_port,
                                        protocol='pbc').bucket_type('sets')
                bucket = btype.bucket(RiakDirectoryBucketNamespace)
                myset = datatypes.Set(bucket, RiakKeyNamespace)
                myset.reload()
                if len(myset) > 0:
                    the_file_size = int(next(iter(myset)))
                    logger.debug('Got size: %s' % (str(the_file_size)))
                else:
                    the_file_size = None

                if (the_file_size is None):
                    logger.debug(
                        'Requested file %s apparently not existing in %s checking locally...'
                        % (RiakKeyNamespace, RiakDirectoryBucketNamespace))
                    if os.path.isfile(full_path):
                        logger.debug(
                            'file exists locally - using this one...(%s)' %
                            (full_path))
                        return dict(st_mode=(S_IFREG
                                             | riak_contents_file_mask),
                                    st_nlink=1,
                                    st_uid=riak_contents_file_uid,
                                    st_gid=riak_contents_file_gid,
                                    st_size=os.path.getsize(full_path),
                                    st_ctime=time(),
                                    st_mtime=time(),
                                    st_atime=time())
                    else:
                        raise FuseOSError(errno.ENOENT)
                else:
                    # You've now got a ``RiakObject``. To get at the binary data, call:
                    return dict(st_mode=(S_IFREG | riak_contents_file_mask),
                                st_nlink=1,
                                st_uid=riak_contents_file_uid,
                                st_gid=riak_contents_file_gid,
                                st_size=the_file_size,
                                st_ctime=time(),
                                st_mtime=time(),
                                st_atime=time())
        else:
            st = os.lstat(full_path)

        logger.debug('Attributes: %s' % (st))
        return dict((key, getattr(st, key))
                    for key in ('st_atime', 'st_ctime', 'st_gid', 'st_mode',
                                'st_mtime', 'st_nlink', 'st_size', 'st_uid'))
Esempio n. 5
0
    def release(self, path, fh):
        logger.debug('release %s - fh: %s' % (path, fh))

        # First step: get the correct names for buckets and keys
        RiakBucketNamespace = NameMapping.legacyPathToRiakBucketName(
            riak_namespace_prefix, path)
        RiakKeyNamespace = NameMapping.legacyPathToRiakKeyName(path)
        RiakDirectoryBucketNamespace = NameMapping.legacyPathToRiakBucketName(
            riak_directory_namespace_prefix, path)

        # this is not a valid namespace - so pattern did not match on a directory/filename structure known to be mapped
        # --> therefore this method will return to the caller now.
        if RiakBucketNamespace is None:
            # apparently this is not a proper path, so just go ahead and close the handle but report
            logger.warning('%s is not a mappable RIAK bucket - ignoring.' %
                           (path))
            return os.close(fh)

        # this seems to be a mappable RIAK path - so let's log and move on to actually moving the file to RIAK
        logger.debug(
            'updating on RIAK bucket %s the key %s (%s bytes to write.)' %
            (RiakBucketNamespace, RiakKeyNamespace,
             os.path.getsize(self._full_path(path))))

        try:
            # create RiakClient instance
            riakClient = riak.RiakClient(host=riak_host,
                                         pb_port=riak_port,
                                         protocol='pbc')
            # get the correct bucket
            release_bucket = riakClient.bucket(RiakBucketNamespace)
            # open the local file for read access off the filesystem
            the_imge_data = open(self._full_path(path), 'rb').read()
            # get the key+value and add it to the bucket
            riak_image = release_bucket.new(RiakKeyNamespace,
                                            encoded_data=the_imge_data,
                                            content_type=riak_content_type)
            # send to RIAK afterall
            riak_image.store()
        except Exception as e:
            logger.error(
                'ERROR updating on RIAK bucket %s the key %s (Exception: %s)' %
                (RiakBucketNamespace, RiakKeyNamespace, str(e)))
        else:
            logger.debug('DONE updating on RIAK bucket %s the key %s' %
                         (RiakBucketNamespace, RiakKeyNamespace))
            # is the directory structure (also) maintained in RIAK - if so, go ahead and update properly
            if (maintain_riak_directory_structure):
                logger.debug('updating %s directory structure for %s' %
                             (RiakDirectoryBucketNamespace, RiakKeyNamespace))
                # Updating the $prefix+$id+$directoryprefix set with the given information
                # we shall use our own riak client instance for this
                btype = riak.RiakClient(
                    host=riak_host, pb_port=riak_port,
                    protocol='pbc').bucket_type(riak_directory_set_buckettype)
                # get the bucket for the directory namespace - this is a sets pre-configured bucket
                bucket = btype.bucket(RiakDirectoryBucketNamespace)
                # get the correct key inside that bucket
                myset = datatypes.Set(bucket, riak_directory_set_directorykey)
                # add this file to the directory - if it's already there it won't be added (handled by RIAK)
                myset.add(RiakKeyNamespace)

                logger.debug('updating size (%s) entry in directory %s/%s' %
                             (str(os.stat(self._full_path(path)).st_size),
                              RiakDirectoryBucketNamespace, RiakKeyNamespace))
                btype.bucket(RiakDirectoryBucketNamespace).new(
                    RiakKeyNamespace,
                    encoded_data=str(os.stat(self._full_path(path)).st_size),
                    content_type=riak_content_type)
                mysizeset = datatypes.Set(bucket, RiakKeyNamespace)
                mysizeset.add(str(os.stat(self._full_path(path)).st_size))

                # send to RIAK afterall
                myset.store()
                mysizeset.store()
                logger.debug('DONE updating directory structure')
            # should the local copy of the file be removed or not
            if (remove_local_copy_after_successful_mapping):
                logger.debug('removing local copy %s' % (path))
                # first close it
                returnvalueclose = os.close(fh)
                # then remove it (just locally)
                os.unlink(self._full_path(path))
                # return the correct return value as per close
                return returnvalueclose
            else:
                logger.debug('not removing local copy %s' % (path))
                return os.close(fh)
Esempio n. 6
0
    def unlink(self, path):
        logger.debug('unlink path %s' % (path))

        # all Riak interactions only necessary when this module actually is managing directory structures in RIAK
        if (maintain_riak_directory_structure):
            try:
                # generate the correct names for the buckets and keys
                RiakBucketNamespace = NameMapping.legacyPathToRiakBucketName(
                    riak_namespace_prefix, path)
                RiakKeyNamespace = NameMapping.legacyPathToRiakKeyName(path)
                RiakDirectoryBucketNamespace = NameMapping.legacyPathToRiakBucketName(
                    riak_directory_namespace_prefix, path)

                # this is not a valid namespace - so pattern did not match on a directory/filename structure known to be mapped
                # --> therefore this method will return to the caller now.
                if RiakKeyNamespace is None:
                    # apparently this is not a proper path, so just go ahead and unlink the local file and report on that
                    logger.warning(
                        '%s is not a mappable RIAK bucket - ignoring.' %
                        (path))
                    return os.unlink(self._full_path(path))

                logger.debug(
                    'updating %s directory structure for %s (discarding)' %
                    (RiakDirectoryBucketNamespace, RiakKeyNamespace))
                # Updating the $prefix+$id+$directoryprefix set with the given information
                # we shall use our own riak client instance for this
                btype = riak.RiakClient(
                    host=riak_host, pb_port=riak_port,
                    protocol='pbc').bucket_type(riak_directory_set_buckettype)
                # get the bucket for the directory namespace - this is a sets pre-configured bucket
                bucket = btype.bucket(RiakDirectoryBucketNamespace)
                # get the correct key inside that bucket
                myset = datatypes.Set(bucket, riak_directory_set_directorykey)
                # fetch the directory in order to be change it...
                myset.reload()
                # add this file to the directory - if it's already there it won't be added (handled by RIAK)
                myset.discard(RiakKeyNamespace)

                mysizeset = datatypes.Set(bucket,
                                          RiakKeyNamespace)  # this is the set
                mysizeset.reload()
                logger.debug('SizeSet len %s' % (len(mysizeset)))
                if len(mysizeset) > 0:
                    the_file_size = int(next(iter(mysizeset)))
                    logger.debug('Discarding object size %s in riak %s' %
                                 (the_file_size, RiakKeyNamespace))
                    mysizeset.discard(str(the_file_size))

                # send to RIAK afterall
                #logger.debug('Storing directory structure...')
                myset.store()
                #logger.debug('Storing size structure...')
                mysizeset.store()
                logger.debug('DONE updating directory structure')
                # now update the bucket itself by removing the key
                # create RiakClient instance
                riakClient = riak.RiakClient(host=riak_host,
                                             pb_port=riak_port,
                                             protocol='pbc')
                # get the correct bucket
                release_bucket = riakClient.bucket(RiakBucketNamespace)
                # remove that key
                release_bucket.delete(RiakKeyNamespace)
            except Exception as e:
                # throw controlled exception but do not remove the actual local file due to errors in the process...
                logger.error(
                    'ERROR updating directory structure on RIAK bucket %s the key %s (Exception: %s)'
                    % (RiakDirectoryBucketNamespace, RiakKeyNamespace, str(e)))
                raise FuseOSError(errno.EACCES)

        # finally do the local unlink when all of the above where successful
        if (os.path.exists(self._full_path(path))):
            return os.unlink(self._full_path(path))
        else:
            return
Esempio n. 7
0
    def rename(self, old, new):
        logger.debug('rename %s - target: %s' % (old, new))
        if (maintain_riak_directory_structure):
            # check if this is the directory that matches our patterns
            try:
                # generate the correct names for the buckets and keys
                RiakBucketNamespace = NameMapping.legacyPathToRiakBucketName(
                    riak_namespace_prefix, old)
                RiakNewBucketNamespace = NameMapping.legacyPathToRiakBucketName(
                    riak_namespace_prefix, new)
                RiakKeyNamespace = NameMapping.legacyPathToRiakKeyName(old)
                RiakNewKeyNamespace = NameMapping.legacyPathToRiakKeyName(new)
                RiakDirectoryBucketNamespace = NameMapping.legacyPathToRiakBucketName(
                    riak_directory_namespace_prefix, old)
                RiakDirectoryNewBucketNamespace = NameMapping.legacyPathToRiakBucketName(
                    riak_directory_namespace_prefix, new)
                logger.debug('rename %s %s %s %s' %
                             (RiakKeyNamespace, RiakNewKeyNamespace,
                              RiakDirectoryBucketNamespace,
                              RiakDirectoryNewBucketNamespace))
                # only continue of the Bucket Names match, not supported to rename between buckets
                if (RiakDirectoryBucketNamespace ==
                        RiakDirectoryNewBucketNamespace):
                    # this is not a valid namespace - so pattern did not match on a directory/filename structure known to be mapped
                    # --> therefore this method will return to the caller now.
                    if RiakKeyNamespace is None:
                        # apparently this is not a proper path, so just go ahead and unlink the local file and report on that
                        logger.warning(
                            '%s is not a mappable RIAK bucket - ignoring.' %
                            (old))
                        # so do the local rename anways...
                        return os.rename(self._full_path(old),
                                         self._full_path(new))

                    logger.debug(
                        'updating %s directory structure for %s to %s (renaming)'
                        % (RiakDirectoryBucketNamespace, RiakKeyNamespace,
                           RiakNewKeyNamespace))
                    # Updating the $prefix+$id+$directoryprefix set with the given information
                    # we shall use our own riak client instance for this
                    btype = riak.RiakClient(host=riak_host,
                                            pb_port=riak_port,
                                            protocol='pbc').bucket_type(
                                                riak_directory_set_buckettype)
                    # get the bucket for the directory namespace - this is a sets pre-configured bucket
                    bucket = btype.bucket(RiakDirectoryBucketNamespace)
                    # get the correct key inside that bucket
                    myset = datatypes.Set(bucket,
                                          riak_directory_set_directorykey)
                    # fetch the directory in order to be change it...
                    myset.reload()
                    # add this file to the directory - if it's already there it won't be added (handled by RIAK)
                    myset.discard(RiakKeyNamespace)
                    myset.add(RiakNewKeyNamespace)
                    # send to RIAK afterall
                    myset.store()
                    logger.debug('DONE updating RIAK directory structure')

                    # create RiakClient instance
                    riakClient = riak.RiakClient(host=riak_host,
                                                 pb_port=riak_port,
                                                 protocol='pbc')
                    # get the correct bucket
                    old_bucket = riakClient.bucket(RiakBucketNamespace)
                    new_bucket = riakClient.bucket(RiakNewBucketNamespace)
                    # read the old key contents...
                    the_imge_data = old_bucket.get(RiakKeyNamespace)
                    logger.debug('Got the old key contents from RIAK (%s/%s)' %
                                 (RiakBucketNamespace, RiakKeyNamespace))
                    # and write those to the new bucket...
                    riak_image = new_bucket.new(RiakNewKeyNamespace,
                                                encoded_data=the_imge_data,
                                                content_type=riak_content_type)
                    logger.debug('Wrote contents to RIAK %s' %
                                 (RiakNewKeyNamespace))
                    # remove the old one...
                    old_bucket.delete(RiakKeyNamespace)
                    logger.debug('Removed old key from RIAK %s' %
                                 (RiakKeyNamespace))
                    # send to RIAK afterall
                    riak_image.store()
                    # if the local copy is removed, it's gone anyways...
                    if not (remove_local_copy_after_successful_mapping):
                        # we shall now rename the local file and finish...
                        return os.rename(self._full_path(old),
                                         self._full_path(new))
                else:
                    logger.debug(
                        'ERROR unsupported rename of file between buckets (%s -> %s)'
                        % (RiakDirectoryBucketNamespace,
                           RiakDirectoryNewBucketNamespace))
                    raise FuseOSError(errno.ENOTSUP)
            except Exception as e:
                # throw controlled exception but do not remove the actual local file due to errors in the process...
                logger.error(
                    'ERROR updating directory structure on RIAK bucket %s the key %s (Exception: %s)'
                    % (RiakDirectoryBucketNamespace, RiakKeyNamespace, str(e)))
                raise FuseOSError(errno.EACCES)
        else:
            # go ahead and rename locally
            return os.rename(self._full_path(old), self._full_path(new))
Esempio n. 8
0
#!/usr/bin/env python

# Quick test

import NameMapping

print(
    NameMapping.legacyPathToRiakBucketName(
        'IMG_',
        '/fdaf16c657d997656bbccc5752eefa9f/images/1620028670_192497.jpg'))
print(
    NameMapping.legacyPathToRiakBucketName(
        'IMG_', '/fdaf16c657d997656bbccc5752eefa9f/images/'))
print(
    NameMapping.legacyPathToRiakBucketName(
        'IMG_', '/fdaf16c657d997656bbccc5752eefa9f/images'))
print(
    NameMapping.legacyPathToRiakKeyName(
        '/fdaf16c657d997656bbccc5752eefa9f/images/1620028670_192497.jpg'))
print(
    NameMapping.legacyPathToRiakKeyName(
        '/fdaf16c657d997656bbccc5752eefa9f/imes/1620028670_192497.jpg'))