Module srboo
[hide private]
[frames] | no frames]

Source Code for Module srboo

  1   
  2  ################################################################ 
  3  # 
  4  # Description: Object Oriented wrapper to Python SRB Interface 
  5  # Author:      Rob Sanderson (azaroth@liv.ac.uk) 
  6  # Date:        2005-05-12 
  7  # Version:     0.8  
  8  # Copyright:   (c) University of Liverpool 
  9  # Licence:     GPL 
 10  # 
 11  ################################################################ 
 12   
 13   
 14  import srb 
 15  import types 
 16  import socket 
 17  import atexit 
 18  from srbErrors import errmsgs 
 19   
 20   
 21  # To Do: 
 22  # !! Will fail at greater than MAX_GET_RESULT objects per collection 
 23   
 24   
 25  # Ensure polite disconnect behaviour 
 26  connections = [] 
27 -def disconnect_all():
28 for c in connections: 29 try: 30 c.disconnect() 31 except: 32 pass
33 atexit.register(disconnect_all) 34 35
36 -class SrbException(Exception):
37 - def __init__(self, type, info=""):
38 self.type = type 39 self.message = errmsgs[type] 40 self.info = info
41
42 - def __repr__(self):
43 return "<<SrbException: (%s) %s>>" % (self.message, self.info)
44 - def __str__(self):
45 return "<<SrbException: (%s) %s>>" % (self.message, self.info)
46 47 48
49 -class SrbFile(object):
50 conn = None 51 fd = -1 52 name = "" 53 collection = "" 54 # Maybe store index in collection? 55 # For wrapper to get non-name metadata 56 position = 0 57
58 - def __init__(self, conn, name):
59 self.conn = conn 60 self.name = name 61 if not conn.collection: 62 raise TypeError("Connection does not have a collection set.") 63 else: 64 self.collection = conn.collection
65 66
67 - def _connect(self, flag):
68 fd = srb.obj_open(self.conn.id, self.collection, self.name, flag) 69 if (fd < 0): 70 raise SrbException(fd, "Failed to open %s" % self.name) 71 else: 72 self.fd = fd
73
74 - def _create(self, size, resource, type, path):
75 fd = srb.obj_create(self.conn.id, 0, self.name, type, resource, 76 self.collection, path, size) 77 if fd < 0: 78 raise SrbException(fd, "Failed to create %s" % self.name) 79 else: 80 self.fd = fd
81
82 - def fileno(self):
83 return self.fd
84
85 - def isatty(self):
86 return False
87
88 - def flush(self):
89 # SRB auto flushes 90 return None
91
92 - def tell(self):
93 return self.position
94
95 - def read(self, size=-1):
96 if self.fd < 0: 97 raise TypeError('File is not open.') 98 if size > -1: 99 data = srb.obj_read(self.conn.id, self.fd, size) 100 self.position += size 101 else: 102 data = "" 103 while 1: 104 buffer = srb.obj_read(self.conn.id, self.fd, 1024) 105 self.position += 1024 106 if buffer == "": break 107 data += buffer 108 return data
109
110 - def close(self):
111 if self.fd < 0: 112 raise TypeError('File is not open.') 113 resp = srb.obj_close(self.conn.id, self.fd) 114 if resp < 0: 115 raise SrbException(resp) 116 else: 117 self.fd = -1
118
119 - def write(self, value):
120 if self.fd < 0: 121 raise TypeError('File is not open.') 122 #if type(value) == types.UnicodeType: 123 # try: 124 # value = value.encode('utf-8') 125 # except: 126 # raise TypeError("Cannot map unicode object to srb-writable string.") 127 #elif type(value) != types.StringType: 128 # raise TypeError("Can only write strings to SRB") 129 130 resp = srb.obj_write(self.conn.id, self.fd, value, len(value)) 131 if resp < 0: 132 raise SrbException(resp) 133 else: 134 return resp
135
136 - def seek(self, offset, whence=0):
137 if self.fd < 0: 138 raise TypeError('File is not open.') 139 resp = srb.obj_seek(self.conn.id, self.fd, offset, whence) 140 if resp < 0: 141 raise SrbException(resp) 142 else: 143 self.position = whence + offset
144
145 - def delete(self, copynum=0):
146 resp = srb.obj_delete(self.conn.id, self.name, copynum, self.collection) 147 if resp < 0: 148 raise SrbException(resp)
149
150 - def get_umetadata(self):
151 md = srb.get_user_metadata(self.conn.id, self.name, self.connection) 152 if typeof(md) == types.IntType: 153 if (md == -3005): 154 md = {} 155 else: 156 raise SrbException(md) 157 return md
158
159 - def set_umetadata(self, f, v):
160 try: 161 self.delete_umetadata(f) 162 except: 163 pass 164 status = srb.set_user_metadata(self.conn.id, self.name, self.collection, f, v) 165 if status < 0: 166 raise SrbException(status) 167 else: 168 return status
169
170 - def delete_umetadata(self, f):
171 md = self.get_umetadata() 172 if (md.has_key(f)): 173 status = srb.rm_user_metadata(self.conn.id, self.name, self.connection, f, md[f]) 174 else: 175 status = 0 176 if status < 0: 177 raise SrbException(status) 178 else: 179 return status
180 181
182 -class SrbConnection(object):
183 id = -1 184 collection = "" 185 resource = "" 186 187 host = "" 188 port = "" 189 domain = "" 190 auth = "" 191 user = "" 192 passwd = "" 193 dn = "" 194
195 - def __init__(self, host, port, domain, auth="ENCRYPT1", user="", passwd="", dn=""):
196 197 # Lookup host to ensure safe 198 try: 199 info = socket.gethostbyname(host) 200 self.host = host 201 except socket.gaierror, e: 202 raise TypeError("Unknown host: %s" % host) 203 204 if type(port) == types.IntType: 205 self.port = str(port) 206 elif type(port) == types.StringType: 207 if port.isdigit(): 208 self.port = port 209 else: 210 raise TypeError("Port must be numeric") 211 else: 212 raise TypeError("Port must be integer or numeric string") 213 214 self.domain = domain 215 216 if auth == "PASSWD_AUTH": 217 # deprecated 218 self.auth = "ENCRYPT1" 219 elif auth in ["ENCRYPT1", "GSI_AUTH"]: 220 self.auth = auth 221 elif not auth and user and passwd: 222 self.auth = "ENCRYPT1" 223 elif not auth and dn: 224 self.auth = "GSI_AUTH" 225 else: 226 print user, passwd 227 raise TypeError("Unknown authentication type: %s" % auth) 228 229 assert self.host 230 assert self.port 231 assert self.domain 232 if self.auth == "ENCRYPT1": 233 assert user 234 assert passwd 235 elif self.auth == "GSI_AUTH": 236 assert dn 237 238 sid = srb.connect(self.host, self.port, self.domain, self.auth, user, passwd, dn) 239 if sid < 0: 240 raise SrbException(sid) 241 else: 242 self.id = sid 243 connections.append(self) 244 self.open_collection("/home/%s.%s" % (user, domain))
245
246 - def disconnect(self):
247 srb.disconnect(self.id)
248
249 - def open(self, name, flag='w'):
250 # Map from 'r', 'a', 'w' to unixFlag int 251 # XXX How to open at end for 'a' ? 252 if flag == 'r': 253 iflag = 0 254 else: 255 iflag = 2 256 f = SrbFile(self, name) 257 f._connect(iflag) 258 return f
259
260 - def create(self, name, size=-1, type="generic", resource="", path=""):
261 f = SrbFile(self, name) 262 if not resource and not self.resource: 263 raise TypeError("Must either give resource or set on connection") 264 elif not resource: 265 resource = self.resource 266 f._create(size, resource, type, path) 267 return f
268
269 - def create_collection(self, name):
270 # Create collection in current 271 resp = srb.mk_collection(self.id, 0, self.collection, name) 272 if resp < 0: 273 raise SrbException(resp)
274
275 - def up_collection(self):
276 new = self.collection[:self.collection.rindex('/')] 277 self.open_collection(new)
278
279 - def open_collection(self, name):
280 if (name[0] != '/'): 281 name = self.collection + '/' + name 282 self.collection = name 283 self.n_objects() 284 self.n_subcollections()
285
286 - def delete_collection(self, recursive=0):
287 resp = srb.rm_collection(self.id, 0, recursive, self.collection) 288 if resp < 0: 289 raise SrbException(resp) 290 else: 291 self.up_collection()
292
293 - def n_subcollections(self):
294 n = srb.get_subcolls(self.id, 0, self.collection) 295 if n < 0: 296 raise SrbException(n) 297 else: 298 self.subcolls = n 299 return n
300
301 - def n_objects(self):
302 # Order of objects by name 303 n = srb.get_objs_in_coll(self.id, 0,2, self.collection) 304 if n < 0: 305 raise SrbException(n) 306 else: 307 self.objects = n 308 return n
309
310 - def object_metadata(self, idx, type='name'):
311 # Will raise if not valid 312 if not self.collection: 313 raise TypeError("Must open a collection first") 314 elif idx >= self.objects: 315 raise IndexError("Object index out of range") 316 t = ['name', 'collection', 'size', 'type', 'owner', 'timestamp', 'replica', 'resource'].index(type) 317 return srb.get_obj_metadata(self.id, t, idx)
318
319 - def collection_name(self, idx):
320 if not self.collection: 321 raise TypeError("Must open a collection first") 322 elif idx >= self.subcolls: 323 raise IndexError("Subcollection index out of range") 324 return srb.get_subcoll_name(self.id, idx)
325 326
327 - def walk_names(self):
328 # Return tuple of colls, files 329 self.n_subcollections() 330 self.n_objects() 331 colls = [] 332 files = [] 333 for s in range(self.subcolls): 334 colls.append(self.collection_name(s)) 335 for f in range(self.objects): 336 files.append(self.object_metadata(f)) 337 return (colls, files)
338
339 - def walk(self):
340 # Following os.walk 341 # (Leaves you in lowest leaf) 342 (colls, files) = self.walk_names() 343 yield self.collection, colls, files 344 for name in colls: 345 self.open_collection(name) 346 for x in self.walk(): 347 yield x
348 349
350 - def rmrf(self):
351 for path, dirs, files in self.walk(): 352 for file in files: 353 f = self.open(file) 354 f.close() 355 f.delete()
356