summaryrefslogtreecommitdiffstats
path: root/glusterfs
diff options
context:
space:
mode:
authorHumble Chirammal <hchiramm@redhat.com>2015-02-17 17:26:43 +0530
committerhchiramm <hchiramm@redhat.com>2015-04-25 13:24:33 +0530
commit75bb7da7094e0344fc7be93408ff6d6ead855253 (patch)
tree7fe491ac83a1cb94dc992d4eea344c7edc5137a3 /glusterfs
parent436a05174b96a90216925424bbb8bb1bcbb1eb2e (diff)
Rename module name from glusterfs to gluster
The goal is to consolidate all gluster related python packages under single namespace "gluster". From client's perspective, it was: from glusterfs import gfapi Henceforth, it wil be: from gluster import gfapi Change-Id: If2509f570563ae7660892963607c9474313f803c Signed-off-by: Humble Chirammal <hchiramm@redhat.com>
Diffstat (limited to 'glusterfs')
-rw-r--r--glusterfs/__init__.py47
-rwxr-xr-xglusterfs/api.py402
-rwxr-xr-xglusterfs/gfapi.py578
3 files changed, 0 insertions, 1027 deletions
diff --git a/glusterfs/__init__.py b/glusterfs/__init__.py
deleted file mode 100644
index 900183b..0000000
--- a/glusterfs/__init__.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# 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.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-class PkgInfo(object):
- def __init__(self, canonical_version, release, name, final):
- self.canonical_version = canonical_version
- self.release = release
- self.name = name
- self.final = final
-
- def save_config(self, filename):
- """
- Creates a file with the package configuration which can be sourced by
- a bash script.
- """
- with open(filename, 'w') as fd:
- fd.write("NAME=%s\n" % self.name)
- fd.write("VERSION=%s\n" % self.canonical_version)
- fd.write("RELEASE=%s\n" % self.release)
-
- @property
- def pretty_version(self):
- if self.final:
- return self.canonical_version
- else:
- return '%s-dev' % (self.canonical_version,)
-
-
-###
-### Change the Package version here
-###
-_pkginfo = PkgInfo('0.0.1', '0', 'python-libgfapi', False)
-__version__ = _pkginfo.pretty_version
-__canonical_version__ = _pkginfo.canonical_version
diff --git a/glusterfs/api.py b/glusterfs/api.py
deleted file mode 100755
index 803a778..0000000
--- a/glusterfs/api.py
+++ /dev/null
@@ -1,402 +0,0 @@
-
-# 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.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import ctypes
-from ctypes.util import find_library
-
-
-# Looks like ctypes is having trouble with dependencies, so just force them to
-# load with RTLD_GLOBAL until I figure that out.
-client = ctypes.CDLL(find_library("gfapi"), ctypes.RTLD_GLOBAL, use_errno=True)
-# The above statement "may" fail with OSError on some systems if libgfapi.so
-# is located in /usr/local/lib/. This happens when glusterfs is installed from
-# source. Refer to: http://bugs.python.org/issue18502
-
-# Wow, the Linux kernel folks really play nasty games with this structure. If
-# you look at the man page for stat(2) and then at this definition you'll note
-# two discrepancies. First, we seem to have st_nlink and st_mode reversed. In
-# fact that's exactly how they're defined *for 64-bit systems*; for 32-bit
-# they're in the man-page order. Even uglier, the man page makes no mention of
-# the *nsec fields, but they are very much present and if they're not included
-# then we get memory corruption because libgfapi has a structure definition
-# that's longer than ours and they overwrite some random bit of memory after
-# the space we allocated. Yes, that's all very disgusting, and I'm still not
-# sure this will really work on 32-bit because all of the field types are so
-# obfuscated behind macros and feature checks.
-
-
-class Stat (ctypes.Structure):
- _fields_ = [
- ("st_dev", ctypes.c_ulong),
- ("st_ino", ctypes.c_ulong),
- ("st_nlink", ctypes.c_ulong),
- ("st_mode", ctypes.c_uint),
- ("st_uid", ctypes.c_uint),
- ("st_gid", ctypes.c_uint),
- ("st_rdev", ctypes.c_ulong),
- ("st_size", ctypes.c_ulong),
- ("st_blksize", ctypes.c_ulong),
- ("st_blocks", ctypes.c_ulong),
- ("st_atime", ctypes.c_ulong),
- ("st_atimensec", ctypes.c_ulong),
- ("st_mtime", ctypes.c_ulong),
- ("st_mtimensec", ctypes.c_ulong),
- ("st_ctime", ctypes.c_ulong),
- ("st_ctimensec", ctypes.c_ulong),
- ]
-
-
-class Statvfs (ctypes.Structure):
- _fields_ = [
- ("f_bsize", ctypes.c_ulong),
- ("f_frsize", ctypes.c_ulong),
- ("f_blocks", ctypes.c_ulong),
- ("f_bfree", ctypes.c_ulong),
- ("f_bavail", ctypes.c_ulong),
- ("f_files", ctypes.c_ulong),
- ("f_ffree", ctypes.c_ulong),
- ("f_favail", ctypes.c_ulong),
- ("f_fsid", ctypes.c_ulong),
- ("f_flag", ctypes.c_ulong),
- ("f_namemax", ctypes.c_ulong),
- ("__f_spare", ctypes.c_int * 6),
- ]
-
-
-class Dirent (ctypes.Structure):
- _fields_ = [
- ("d_ino", ctypes.c_ulong),
- ("d_off", ctypes.c_ulong),
- ("d_reclen", ctypes.c_ushort),
- ("d_type", ctypes.c_char),
- ("d_name", ctypes.c_char * 256),
- ]
-
-
-# Here is the reference card of libgfapi library exported
-# apis with its different versions.
-#
-# GFAPI_3.4.0 {
-# glfs_new;
-# glfs_set_volfile;
-# glfs_set_volfile_server;
-# glfs_set_logging;
-# glfs_init;
-# glfs_fini;
-# glfs_open;
-# glfs_creat;
-# glfs_close;
-# glfs_from_glfd;
-# glfs_set_xlator_option;
-# glfs_read;
-# glfs_write;
-# glfs_read_async;
-# glfs_write_async;
-# glfs_readv;
-# glfs_writev;
-# glfs_readv_async;
-# glfs_writev_async;
-# glfs_pread;
-# glfs_pwrite;
-# glfs_pread_async;
-# glfs_pwrite_async;
-# glfs_preadv;
-# glfs_pwritev;
-# glfs_preadv_async;
-# glfs_pwritev_async;
-# glfs_lseek;
-# glfs_truncate;
-# glfs_ftruncate;
-# glfs_ftruncate_async;
-# glfs_lstat;
-# glfs_stat;
-# glfs_fstat;
-# glfs_fsync;
-# glfs_fsync_async;
-# glfs_fdatasync;
-# glfs_fdatasync_async;
-# glfs_access;
-# glfs_symlink;
-# glfs_readlink;
-# glfs_mknod;
-# glfs_mkdir;
-# glfs_unlink;
-# glfs_rmdir;
-# glfs_rename;
-# glfs_link;
-# glfs_opendir;
-# glfs_readdir_r;
-# glfs_readdirplus_r;
-# glfs_telldir;
-# glfs_seekdir;
-# glfs_closedir;
-# glfs_statvfs;
-# glfs_chmod;
-# glfs_fchmod;
-# glfs_chown;
-# glfs_lchown;
-# glfs_fchown;
-# glfs_utimens;
-# glfs_lutimens;
-# glfs_futimens;
-# glfs_getxattr;
-# glfs_lgetxattr;
-# glfs_fgetxattr;
-# glfs_listxattr;
-# glfs_llistxattr;
-# glfs_flistxattr;
-# glfs_setxattr;
-# glfs_lsetxattr;
-# glfs_fsetxattr;
-# glfs_removexattr;
-# glfs_lremovexattr;
-# glfs_fremovexattr;
-# glfs_getcwd;
-# glfs_chdir;
-# glfs_fchdir;
-# glfs_realpath;
-# glfs_posix_lock;
-# glfs_dup;
-#
-# }
-#
-# GFAPI_3.4.2 {
-# glfs_setfsuid;
-# glfs_setfsgid;
-# glfs_setfsgroups;
-# glfs_h_lookupat;
-# glfs_h_creat;
-# glfs_h_mkdir;
-# glfs_h_mknod;
-# glfs_h_symlink;
-# glfs_h_unlink;
-# glfs_h_close;
-# glfs_h_truncate;
-# glfs_h_stat;
-# glfs_h_getattrs;
-# glfs_h_setattrs;
-# glfs_h_readlink;
-# glfs_h_link;
-# glfs_h_rename;
-# glfs_h_extract_handle;
-# glfs_h_create_from_handle;
-# glfs_h_opendir;
-# glfs_h_open;
-# }
-#
-# GFAPI_3.5.0 {
-#
-# glfs_get_volumeid;
-# glfs_readdir;
-# glfs_readdirplus;
-# glfs_fallocate;
-# glfs_discard;
-# glfs_discard_async;
-# glfs_zerofill;
-# glfs_zerofill_async;
-# glfs_caller_specific_init;
-# glfs_h_setxattrs;
-#
-# }
-#
-# GFAPI_3.5.1 {
-#
-# glfs_unset_volfile_server;
-# glfs_h_getxattrs;
-# glfs_h_removexattrs;
-#
-# }
-#
-# GFAPI_3.6.0 {
-#
-# glfs_get_volfile;
-# glfs_h_access;
-#
-# }
-#
-
-# Define function prototypes for the wrapper functions.
-
-glfs_init = ctypes.CFUNCTYPE(
- ctypes.c_int, ctypes.c_void_p)(('glfs_init', client))
-
-glfs_statvfs = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_void_p)(('glfs_statvfs', client))
-
-glfs_new = ctypes.CFUNCTYPE(
- ctypes.c_void_p, ctypes.c_char_p)(('glfs_new', client))
-
-glfs_set_volfile_server = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_char_p,
- ctypes.c_int)(('glfs_set_volfile_server', client)) # noqa
-
-glfs_set_logging = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_int)(('glfs_set_logging', client))
-
-glfs_fini = ctypes.CFUNCTYPE(
- ctypes.c_int, ctypes.c_void_p)(('glfs_fini', client))
-
-
-glfs_close = ctypes.CFUNCTYPE(
- ctypes.c_int, ctypes.c_void_p)(('glfs_close', client))
-
-glfs_lstat = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_char_p,
- ctypes.POINTER(Stat))(('glfs_lstat', client))
-
-glfs_stat = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_char_p,
- ctypes.POINTER(Stat))(('glfs_stat', client))
-
-glfs_fstat = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.POINTER(
- Stat))(('glfs_fstat', client))
-
-glfs_chmod = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_ushort)(('glfs_chmod', client))
-
-glfs_fchmod = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_ushort)(('glfs_fchmod', client))
-
-glfs_chown = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_uint,
- ctypes.c_uint)(('glfs_chown', client))
-
-glfs_lchown = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_uint,
- ctypes.c_uint)(('glfs_lchown', client))
-
-glfs_fchown = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_uint,
- ctypes.c_uint)(('glfs_fchown', client))
-
-glfs_dup = ctypes.CFUNCTYPE(
- ctypes.c_void_p, ctypes.c_void_p)(('glfs_dup', client))
-
-glfs_fdatasync = ctypes.CFUNCTYPE(
- ctypes.c_int, ctypes.c_void_p)(('glfs_fdatasync', client))
-
-glfs_fsync = ctypes.CFUNCTYPE(
- ctypes.c_int, ctypes.c_void_p)(('glfs_fsync', client))
-
-glfs_lseek = ctypes.CFUNCTYPE(ctypes.c_ulong, ctypes.c_void_p, ctypes.c_ulong,
- ctypes.c_int)(('glfs_lseek', client))
-
-glfs_read = ctypes.CFUNCTYPE(ctypes.c_size_t,
- ctypes.c_void_p,
- ctypes.c_void_p,
- ctypes.c_size_t,
- ctypes.c_int)(('glfs_read', client))
-
-glfs_write = ctypes.CFUNCTYPE(ctypes.c_size_t,
- ctypes.c_void_p,
- ctypes.c_void_p,
- ctypes.c_size_t,
- ctypes.c_int)(('glfs_write', client))
-
-glfs_getxattr = ctypes.CFUNCTYPE(ctypes.c_size_t,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_char_p,
- ctypes.c_void_p,
- ctypes.c_size_t)(('glfs_getxattr', client))
-
-glfs_listxattr = ctypes.CFUNCTYPE(ctypes.c_size_t,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_void_p,
- ctypes.c_size_t)(('glfs_listxattr', client))
-
-glfs_removexattr = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_char_p)(('glfs_removexattr', client)) # noqa
-
-glfs_setxattr = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_char_p,
- ctypes.c_void_p,
- ctypes.c_size_t,
- ctypes.c_int)(('glfs_setxattr', client))
-
-glfs_rename = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_char_p)(('glfs_rename', client))
-
-glfs_symlink = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p,
- ctypes.c_char_p)(('glfs_symlink', client))
-
-glfs_unlink = ctypes.CFUNCTYPE(
- ctypes.c_int, ctypes.c_void_p, ctypes.c_char_p)(('glfs_unlink', client))
-
-glfs_readdir_r = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p,
- ctypes.POINTER(Dirent),
- ctypes.POINTER(ctypes.POINTER(Dirent)))(('glfs_readdir_r', client)) # noqa
-
-glfs_closedir = ctypes.CFUNCTYPE(
- ctypes.c_int, ctypes.c_void_p)(('glfs_closedir', client))
-
-
-glfs_mkdir = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_char_p,
- ctypes.c_ushort)(('glfs_mkdir', client))
-
-glfs_opendir = ctypes.CFUNCTYPE(ctypes.c_void_p,
- ctypes.c_void_p,
- ctypes.c_char_p)(('glfs_opendir', client))
-
-glfs_rmdir = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_void_p,
- ctypes.c_char_p)(('glfs_rmdir', client))
-
-glfs_setfsuid = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_uint)(('glfs_setfsuid', client))
-
-glfs_setfsgid = ctypes.CFUNCTYPE(ctypes.c_int,
- ctypes.c_uint)(('glfs_setfsgid', client))
-
-
-# TODO: creat and open fails on test_create_file_already_exists & test_open_file_not_exist functional testing, # noqa
-# when defined via function prototype.. Need to find RCA. For time being, using it from 'api.glfs_' # noqa
-#_glfs_creat = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int, ctypes.c_uint) # noqa
- # (('glfs_creat', client)) # noqa
-#_glfs_open = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int) # noqa
-# (('glfs_open', client)) # noqa
-# TODO: # discard and fallocate fails with "AttributeError: /lib64/libgfapi.so.0: undefined symbol: glfs_discard", # noqa
-# for time being, using it from api.* # noqa
-# glfs_discard = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_size_t)(('glfs_discard', client)) # noqa
-#_glfs_fallocate = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_ulong, ctypes.c_size_t) # noqa
-# (('glfs_fallocate', client)) # noqa
-
-
-#glfs_creat = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int, ctypes.c_uint)(('glfs_creat', client)) # noqa
-#glfs_open = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int)(('glfs_open', client)) # noqa
-
-#glfs_discard = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_ulong, ctypes.c_size_t)(('glfs_discard', client)) # noqa
-#glfs_fallocate = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_int, ctypes.c_ulong, ctypes.c_size_t)(('glfs_fallocate', client)) # noqa
diff --git a/glusterfs/gfapi.py b/glusterfs/gfapi.py
deleted file mode 100755
index 42c4aef..0000000
--- a/glusterfs/gfapi.py
+++ /dev/null
@@ -1,578 +0,0 @@
-# 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.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import ctypes
-import os
-import stat
-import errno
-from glusterfs import api
-
-
-class File(object):
-
- def __init__(self, fd, path=None):
- self.fd = fd
- self.originalpath = path
-
- def __enter__(self):
- if self.fd is None:
- # __enter__ should only be called within the context
- # of a 'with' statement when opening a file through
- # Volume.open()
- raise ValueError("I/O operation on closed file")
- return self
-
- def __exit__(self, type, value, tb):
- self.close()
-
- def close(self):
- ret = api.glfs_close(self.fd)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def discard(self, offset, len):
- ret = api.client.glfs_discard(self.fd, offset, len)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def dup(self):
- dupfd = api.glfs_dup(self.fd)
- if not dupfd:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return File(dupfd, self.originalpath)
-
- def fallocate(self, mode, offset, len):
- ret = api.client.glfs_fallocate(self.fd, mode, offset, len)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def fchmod(self, mode):
- """
- Change this file's mode
-
- :param mode: new mode
- :returns: 0 if success, raises OSError if it fails
- """
- ret = api.glfs_fchmod(self.fd, mode)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def fchown(self, uid, gid):
- """
- Change this file's owner and group id
-
- :param uid: new user id for file
- :param gid: new group id for file
- :returns: 0 if success, raises OSError if it fails
- """
- ret = api.glfs_fchown(self.fd, uid, gid)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def fdatasync(self):
- """
- Force write of file
-
- :returns: 0 if success, raises OSError if it fails
- """
- ret = api.glfs_fdatasync(self.fd)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def fgetsize(self):
- """
- Return the size of a file, reported by fstat()
- """
- return self.fstat().st_size
-
- def fstat(self):
- """
- Returns Stat object for this file.
- """
- s = api.Stat()
- rc = api.glfs_fstat(self.fd, ctypes.byref(s))
- if rc < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return s
-
- def fsync(self):
- ret = api.glfs_fsync(self.fd)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def lseek(self, pos, how):
- """
- Set the read/write offset position of this file.
- The new position is defined by 'pos' relative to 'how'
-
- :param pos: sets new offset position according to 'how'
- :param how: SEEK_SET, sets offset position 'pos' bytes relative to
- beginning of file, SEEK_CUR, the position is set relative
- to the current position and SEEK_END sets the position
- relative to the end of the file.
- :returns: the new offset position
-
- """
- return api.glfs_lseek(self.fd, pos, how)
-
- def read(self, buflen=-1):
- """
- read file
-
- :param buflen: length of read buffer. If less than 0, then whole
- file is read. Default is -1.
- :returns: buffer of size buflen
- """
- if buflen < 0:
- buflen = self.fgetsize()
- rbuf = ctypes.create_string_buffer(buflen)
- ret = api.glfs_read(self.fd, rbuf, buflen, 0)
- if ret > 0:
- return rbuf
- elif ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- else:
- return ret
-
- def write(self, data, flags=0):
- # creating a ctypes.c_ubyte buffer to handle converting bytearray
- # to the required C data type
-
- if type(data) is bytearray:
- buf = (ctypes.c_ubyte * len(data)).from_buffer(data)
- else:
- buf = data
- ret = api.glfs_write(self.fd, buf, len(buf), flags)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
-
-class Dir(object):
-
- def __init__(self, fd):
- # Add a reference so the module-level variable "api" doesn't
- # get yanked out from under us (see comment above File def'n).
- self._api = api
- self.fd = fd
- self.cursor = ctypes.POINTER(api.Dirent)()
-
- def __del__(self):
- self._api.glfs_closedir(self.fd)
- self._api = None
-
- def next(self):
- entry = api.Dirent()
- entry.d_reclen = 256
- rc = api.glfs_readdir_r(self.fd, ctypes.byref(entry),
- ctypes.byref(self.cursor))
-
- if (rc < 0) or (not self.cursor) or (not self.cursor.contents):
- return rc
-
- return entry
-
-
-class Volume(object):
-
- def __init__(self, host, volid, proto="tcp", port=24007):
- # Add a reference so the module-level variable "api" doesn't
- # get yanked out from under us (see comment above File def'n).
- self._api = api
- self.fs = api.glfs_new(volid)
- api.glfs_set_volfile_server(self.fs, proto, host, port)
-
- def __del__(self):
- self._api.glfs_fini(self.fs)
- self._api = None
-
- def set_logging(self, path, level):
- api.glfs_set_logging(self.fs, path, level)
-
- def mount(self):
- return api.glfs_init(self.fs)
-
- def chmod(self, path, mode):
- """
- Change mode of path
-
- :param path: the item to be modified
- :mode: new mode
- :returns: 0 if success, raises OSError if it fails
- """
- ret = api.glfs_chmod(self.fs, path, mode)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def chown(self, path, uid, gid):
- """
- Change owner and group id of path
-
- :param path: the item to be modified
- :param uid: new user id for item
- :param gid: new group id for item
- :returns: 0 if success, raises OSError if it fails
- """
- ret = api.glfs_chown(self.fs, path, uid, gid)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def exists(self, path):
- """
- Test whether a path exists.
- Returns False for broken symbolic links.
- """
- try:
- self.stat(path)
- except OSError:
- return False
- return True
-
- def getatime(self, path):
- """
- Returns the last access time as reported by stat
- """
- return self.stat(path).st_atime
-
- def getctime(self, path):
- """
- Returns the time when changes were made to the path as reported by stat
- This time is updated when changes are made to the file or dir's inode
- or the contents of the file
- """
- return self.stat(path).st_ctime
-
- def getmtime(self, path):
- """
- Returns the time when changes were made to the content of the path
- as reported by stat
- """
- return self.stat(path).st_mtime
-
- def getsize(self, filename):
- """
- Return the size of a file, reported by stat()
- """
- return self.stat(filename).st_size
-
- def getxattr(self, path, key, maxlen):
- buf = ctypes.create_string_buffer(maxlen)
- rc = api.glfs_getxattr(self.fs, path, key, buf, maxlen)
- if rc < 0:
- err = ctypes.get_errno()
- raise IOError(err, os.strerror(err))
- return buf.value[:rc]
-
- def isdir(self, path):
- """
- Test whether a path is an existing directory
- """
- try:
- s = self.stat(path)
- except OSError:
- return False
- return stat.S_ISDIR(s.st_mode)
-
- def isfile(self, path):
- """
- Test whether a path is a regular file
- """
- try:
- s = self.stat(path)
- except OSError:
- return False
- return stat.S_ISREG(s.st_mode)
-
- def islink(self, path):
- """
- Test whether a path is a symbolic link
- """
- try:
- s = self.lstat(path)
- except OSError:
- return False
- return stat.S_ISLNK(s.st_mode)
-
- def listdir(self, path):
- """
- Return list of entries in a given directory 'path'.
- "." and ".." are not included, and the list is not sorted.
- """
- d = self.opendir(path)
- dir_list = []
- while True:
- ent = d.next()
- if not isinstance(ent, api.Dirent):
- break
- name = ent.d_name[:ent.d_reclen]
- if not name in [".", ".."]:
- dir_list.append(name)
- return dir_list
-
- def listxattr(self, path):
- buf = ctypes.create_string_buffer(512)
- rc = api.glfs_listxattr(self.fs, path, buf, 512)
- if rc < 0:
- err = ctypes.get_errno()
- raise IOError(err, os.strerror(err))
- xattrs = []
- # Parsing character by character is ugly, but it seems like the
- # easiest way to deal with the "strings separated by NUL in one
- # buffer" format.
- i = 0
- while i < rc:
- new_xa = buf.raw[i]
- i += 1
- while i < rc:
- next_char = buf.raw[i]
- i += 1
- if next_char == '\0':
- xattrs.append(new_xa)
- break
- new_xa += next_char
- xattrs.sort()
- return xattrs
-
- def lstat(self, path):
- s = api.Stat()
- rc = api.glfs_lstat(self.fs, path, ctypes.byref(s))
- if rc < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return s
-
- def makedirs(self, name, mode=0777):
- """
- Create directories defined in 'name' recursively.
- """
- head, tail = os.path.split(name)
- if not tail:
- head, tail = os.path.split(head)
- if head and tail and not self.exists(head):
- try:
- self.makedirs(head, mode)
- except OSError as err:
- if err.errno != errno.EEXIST:
- raise
- if tail == os.curdir:
- return
- self.mkdir(name, mode)
-
- def mkdir(self, path, mode=0777):
- ret = api.glfs_mkdir(self.fs, path, mode)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def open(self, path, flags, mode=0777):
- if (os.O_CREAT & flags) == os.O_CREAT:
- #Without direct call to _api the functest fails on creat and open.
-
- fd = api.client.glfs_creat(self.fs, path, flags, mode)
- else:
- fd = api.client.glfs_open(self.fs, path, flags)
- if not fd:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
-
- return File(fd, path)
-
- def opendir(self, path):
- fd = api.glfs_opendir(self.fs, path)
- if not fd:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return Dir(fd)
-
- def removexattr(self, path, key):
- ret = api.glfs_removexattr(self.fs, path, key)
- if ret < 0:
- err = ctypes.get_errno()
- raise IOError(err, os.strerror(err))
- return ret
-
- def rename(self, opath, npath):
- ret = api.glfs_rename(self.fs, opath, npath)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def rmdir(self, path):
- ret = api.glfs_rmdir(self.fs, path)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def rmtree(self, path, ignore_errors=False, onerror=None):
- """
- Delete a whole directory tree structure. Raises OSError
- if path is a symbolic link.
-
- :param path: Directory tree to remove
- :param ignore_errors: If True, errors are ignored
- :param onerror: If set, it is called to handle the error with arguments
- (func, path, exc) where func is the function that
- raised the error, path is the argument that caused it
- to fail; and exc is the exception that was raised.
- If ignore_errors is False and onerror is None, an
- exception is raised
- """
- if ignore_errors:
- def onerror(*args):
- pass
- elif onerror is None:
- def onerror(*args):
- raise
- if self.islink(path):
- raise OSError("Cannot call rmtree on a symbolic link")
- names = []
- try:
- names = self.listdir(path)
- except OSError as e:
- onerror(self.listdir, path, e)
- for name in names:
- fullname = os.path.join(path, name)
- if self.isdir(fullname):
- self.rmtree(fullname, ignore_errors, onerror)
- else:
- try:
- self.unlink(fullname)
- except OSError as e:
- onerror(self.unlink, fullname, e)
- try:
- self.rmdir(path)
- except OSError as e:
- onerror(self.rmdir, path, e)
-
- def setfsuid(self, uid):
- ret = api.glfs_setfsuid(uid)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def setfsgid(self, gid):
- ret = api.glfs_setfsgid(gid)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def setxattr(self, path, key, value, vlen):
- ret = api.glfs_setxattr(self.fs, path, key, value, vlen, 0)
- if ret < 0:
- err = ctypes.get_errno()
- raise IOError(err, os.strerror(err))
- return ret
-
- def stat(self, path):
- s = api.Stat()
- rc = api.glfs_stat(self.fs, path, ctypes.byref(s))
- if rc < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return s
-
- def statvfs(self, path):
- """
- To get status information about the file system that contains the file
- named by the path argument.
- """
- s = api.Statvfs()
- rc = api.glfs_statvfs(self.fs, path, ctypes.byref(s))
- if rc < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return s
-
- def symlink(self, source, link_name):
- """
- Create a symbolic link 'link_name' which points to 'source'
- """
- ret = api.glfs_symlink(self.fs, source, link_name)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def unlink(self, path):
- """
- Delete the file 'path'
-
- :param path: file to be deleted
- :returns: 0 if success, raises OSError if it fails
- """
- ret = api.glfs_unlink(self.fs, path)
- if ret < 0:
- err = ctypes.get_errno()
- raise OSError(err, os.strerror(err))
- return ret
-
- def walk(self, top, topdown=True, onerror=None, followlinks=False):
- """
- Directory tree generator. Yields a 3-tuple dirpath, dirnames, filenames
-
- dirpath is the path to the directory, dirnames is a list of the names
- of the subdirectories in dirpath. filenames is a list of the names of
- the non-directiry files in dirpath
- """
- try:
- names = self.listdir(top)
- except OSError as err:
- if onerror is not None:
- onerror(err)
- return
-
- dirs, nondirs = [], []
- for name in names:
- if self.isdir(os.path.join(top, name)):
- dirs.append(name)
- else:
- nondirs.append(name)
-
- if topdown:
- yield top, dirs, nondirs
- for name in dirs:
- new_path = os.path.join(top, name)
- if followlinks or not self.islink(new_path):
- for x in self.walk(new_path, topdown, onerror, followlinks):
- yield x
- if not topdown:
- yield top, dirs, nondirs