[27529] in Source-Commits
python-afs commit: Add examine and whereis high-level functions
daemon@ATHENA.MIT.EDU (Jonathan D Reed)
Tue Nov 12 18:27:56 2013
Date: Tue, 12 Nov 2013 18:27:50 -0500
From: Jonathan D Reed <jdreed@MIT.EDU>
Message-Id: <201311122327.rACNRopS018748@drugstore.mit.edu>
To: source-commits@MIT.EDU
https://github.com/mit-athena/python-afs/commits/0fc583752fbdc7877578a16d4ced288d5d46c25f
commit 0fc583752fbdc7877578a16d4ced288d5d46c25f
Author: Jonathan Reed <jdreed@mit.edu>
Date: Wed Oct 30 14:13:53 2013 -0400
Add examine and whereis high-level functions
Add high-level functions for "fs examine" and "fs whereis".
Add a convenience function for DNS lookups.
Add logging to afs.fs
afs/fs.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 77 insertions(+), 0 deletions(-)
diff --git a/afs/fs.py b/afs/fs.py
index bd6a638..ca53a30 100644
--- a/afs/fs.py
+++ b/afs/fs.py
@@ -1,6 +1,26 @@
import errno
import os.path
+import socket
+import logging
+import math
+import sys
+
from afs import _fs
+log = logging.getLogger('afs.fs')
+
+class AFSVolumeStatus(object):
+ def __init__(self, volstat):
+ if type(volstat) is not tuple or len(volstat) != 3:
+ raise TypeError("AFSVolumeStatus takes a tuple of (str,str,dict)")
+ if [type(x) for x in volstat] != [str,str,dict]:
+ raise TypeError("AFSVolumeStatus takes a tuple of (str,str,dict)")
+ self.name = volstat[0]
+ self.offline_message = volstat[1]
+ for k,v in volstat[2].items():
+ setattr(self, k, v)
+
+ def __repr__(self):
+ return self.__class__.__name__ + ': ' + repr(self.__dict__)
def whichcell(path):
"""Return the cell name or None if the path is not in AFS"""
@@ -35,3 +55,60 @@ def lsmount(path):
return None
else:
raise
+
+def examine(path):
+ """
+ Given a path in AFS, tells you about the path and volume that
+ contains it. Returns a tuple (volumestatus, fid) where
+ "volumestatus" is an object (with attributes matching the struct
+ VolumeStatus in OpenAFS), as well as some extra attributes, like
+ the volume name, and the offline message. "fid" is a dict with
+ keys matching the VenusFid struct in OpenAFS, or None if the call
+ failed.
+ """
+ try:
+ _volstat = _fs._volume_status(path)
+ except OSError as e:
+ if e.errno == errno.EINVAL:
+ return None
+ else:
+ raise
+ _fid = None
+ try:
+ _fid = _fs._fid(path)
+ except:
+ pass
+ return (AFSVolumeStatus(_volstat), _fid)
+
+def _reverse_lookup(ip):
+ """
+ Convenience function to provide best-effort reverse-resolution
+ """
+ try:
+ return socket.gethostbyaddr(ip)[0]
+ except socket.herror as e:
+ log.debug("Failed to reverse-resolve %s: %s", ip, e)
+ return ip
+ except IndexError:
+ log.warning("IndexError while reverse-resolving IP, shouldn't happen")
+ return ip
+
+def whereis(path, dns=True):
+ """
+ Return a list of hostnames and/or IP addresses representing
+ the AFS file servers where the path can be found.
+
+ Pass dns=False to disable hostname lookup
+ """
+ addrs = []
+ try:
+ addrs = _fs._whereis(path)
+ if dns:
+ return [_reverse_lookup(x) for x in addrs]
+ else:
+ return addrs
+ except OSError as e:
+ if e.errno == errno.EINVAL:
+ return None
+ else:
+ raise