diff options
author | Thiago da Silva <thiago@redhat.com> | 2014-03-18 16:53:10 -0400 |
---|---|---|
committer | Thiago da Silva <thiago@redhat.com> | 2014-03-18 16:53:10 -0400 |
commit | c268302dd4dcd22a503e21f30d5bbfb2df3013f6 (patch) | |
tree | 5b5ce10b96b8727d726e07007ab3482ee62da8ef /gluster | |
parent | 7566a214ba3c5311b3e68a7b916d8850b5c75bf4 (diff) |
changing gluster dir to glusterfs
making this change to avoid package conflicts with
gluster-swift and glusterfs-api rpm. Eventually we will remove
the python code from glusterfs-api rpm and create a new rpm package
from libgfapi-python.
Change-Id: I1b20cd747e500aed17fba89f96e62423325b5230
Signed-off-by: Thiago da Silva <thiago@redhat.com>
Diffstat (limited to 'gluster')
-rw-r--r-- | gluster/__init__.py | 47 | ||||
-rw-r--r-- | gluster/gfapi.py | 538 |
2 files changed, 0 insertions, 585 deletions
diff --git a/gluster/__init__.py b/gluster/__init__.py deleted file mode 100644 index 900183b..0000000 --- a/gluster/__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/gluster/gfapi.py b/gluster/gfapi.py deleted file mode 100644 index 8eeb3d6..0000000 --- a/gluster/gfapi.py +++ /dev/null @@ -1,538 +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 -import os -import stat -import errno - -from contextlib import contextmanager - -# Disclaimer: many of the helper functions (e.g., exists, isdir) where copied -# from the python source code - -# Looks like ctypes is having trouble with dependencies, so just force them to -# load with RTLD_GLOBAL until I figure that out. -api = ctypes.CDLL(find_library("gfapi"), ctypes.RTLD_GLOBAL, use_errno=True) - -# 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 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), - ] - -api.glfs_creat.restype = ctypes.c_void_p -api.glfs_open.restype = ctypes.c_void_p -api.glfs_lstat.restype = ctypes.c_int -api.glfs_lstat.argtypes = [ctypes.c_void_p, ctypes.c_char_p, - ctypes.POINTER(Stat)] -api.glfs_opendir.restype = ctypes.c_void_p -api.glfs_readdir_r.restype = ctypes.c_int -api.glfs_readdir_r.argtypes = [ctypes.c_void_p, ctypes.POINTER(Dirent), - ctypes.POINTER(ctypes.POINTER(Dirent))] -api.glfs_stat.restype = ctypes.c_int -api.glfs_stat.argtypes = [ctypes.c_void_p, ctypes.c_char_p, - ctypes.POINTER(Stat)] -api.glfs_fstat.restype = ctypes.c_int -api.glfs_fstat.argtypes = [ctypes.c_void_p, ctypes.POINTER(Stat)] - - -class File(object): - - def __init__(self, fd): - self.fd = fd - - 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.glfs_discard(self.fd, offset, len) - if ret < 0: - err = ctypes.get_errno() - raise OSError(err, os.strerror(err)) - return ret - - def fallocate(self, mode, offset, len): - ret = api.glfs_fallocate(self.fd, mode, offset, len) - 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 fstat(self): - """ - Returns Stat object for this file. - """ - s = 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 read(self, buflen, flags=0): - rbuf = ctypes.create_string_buffer(buflen) - ret = api.glfs_read(self.fd, rbuf, buflen, flags) - 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): - # 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)) - 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(Dirent)() - - def __del__(self): - self._api.glfs_closedir(self.fd) - self._api = None - - def next(self): - entry = 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): - - # Housekeeping functions. - - 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 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 - - @contextmanager - def creat(self, path, flags, mode): - fd = api.glfs_creat(self.fs, path, flags, mode) - if not fd: - err = ctypes.get_errno() - raise OSError(err, os.strerror(err)) - - fileobj = None - try: - fileobj = File(fd) - yield fileobj - finally: - fileobj.close() - - 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 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, 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 = 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): - """ - 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): - ret = api.glfs_mkdir(self.fs, path, mode) - if ret < 0: - err = ctypes.get_errno() - raise OSError(err, os.strerror(err)) - return ret - - @contextmanager - def open(self, path, flags): - fd = api.glfs_open(self.fs, path, flags) - if not fd: - err = ctypes.get_errno() - raise OSError(err, os.strerror(err)) - - fileobj = None - try: - fileobj = File(fd) - yield fileobj - finally: - fileobj.close() - - 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 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 = 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 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 |