def rename(src, dst): """remote version of operation with same name""" errors = [] # Must appear to be atomic - lock and create copy before removing. (code, servers_string) = distbase.open_session(dst, 'CREATE') if code: raise OSError('%s' % servers_string) (code, servers_string) = distbase.open_session(src, 'DELETE') if code: raise OSError('%s' % servers_string) # In case src is a directory the sessions for all the directory # contents must be modified, too! # TODO: this should really be handled by the storage server (add RENAME session) for server in servers_string.split(' '): try: (status, data) = distbase.http_rename(server, HTTPS_CERT_PORT, '/%s' % src, '/%s' % dst) except Exception as err: errors.append('%s: %s' % (server, err)) continue (code, _) = distbase.close_session(dst, 'CREATE') (code, _) = distbase.close_session(src, 'DELETE') __reraise_errors(errors) __raise_status_errors(status, data)
def __open_remote_file( self, path, mode='r', buf=-1, ): """Request the current leader to open the active session for file with supplied path. """ if -1 != buf: raise IOError('buffered reads are not supported!') # TODO: eliminate need for CREATE in storage code - WRITE # should be enough! if mode.startswith('w'): self.session_type = 'CREATE' distbase.open_session(path, self.session_type) distbase.close_session(path, self.session_type) self.session_type = 'WRITE' else: # TODO: handle other modes like 'a', "r+"? self.session_type = 'READ' return distbase.open_session(path, self.session_type)
def walk(path, topdown=True): """Emulate os.walk() which returns a generator object. We can't pass the raw generator object directly from the server (not even with pickle.dumps()) so we dump a list of the generated (dirpath, dirnames, filenames)-tuples and simply eval() the entire raw string to recover the structure on arrival. """ errors = [] (code, servers_string) = distbase.open_session(path, 'READ') if code: raise OSError('%s' % servers_string) for server in servers_string.split(' '): try: (status, data) = distbase.http_walk(server, HTTPS_CERT_PORT, '/%s' % path, topdown) except Exception as err: errors.append('%s: %s' % (server, err)) continue if not status: break (code, _) = distbase.close_session(path, 'READ') __reraise_errors(errors) __raise_status_errors(status, data) # Remove the added /BASE_HOME from all output filtered_data = data.replace('/%s' % BASE_HOME, '') # recover list of tuples in a way that allows empty list tree = eval('%s' % filtered_data) return __walk_generator(tree)
def symlink(src, dst): """remote version of operation with same name""" errors = [] # Must appear to be atomic - lock and create copy unlocking. (code, servers_string) = distbase.open_session(dst, 'CREATE') if code: raise OSError('%s' % servers_string) # IMPORTANT: src locking disabled since source of symlinks is # not required to exist! # code, servers_string = distbase.open_session(src, "READ") # if code: # raise OSError("%s" % servers_string) for server in servers_string.split(' '): try: (status, data) = distbase.http_symlink(server, HTTPS_CERT_PORT, '/%s' % src, '/%s' % dst) except Exception as err: errors.append('%s: %s' % (server, err)) continue (code, _) = distbase.close_session(dst, 'CREATE') # code, _ = distbase.close_session(src, "READ") __reraise_errors(errors) __raise_status_errors(status, data)
def rmdir(path): """remote version of operation with same name""" errors = [] (code, servers_string) = distbase.open_session(path, 'DELETE') if code: raise OSError('%s' % servers_string) for server in servers_string.split(' '): try: (status, data) = distbase.http_rmdir(server, HTTPS_CERT_PORT, '/%s' % path) except Exception as err: errors.append('%s: %s' % (server, err)) continue (code, _) = distbase.close_session(path, 'DELETE') __reraise_errors(errors) __raise_status_errors(status, data)
def listdir(path): """remote version of operation with same name""" errors = [] (code, servers_string) = distbase.open_session(path, 'READ') if code: raise OSError('%s' % servers_string) for server in servers_string.split(' '): try: (status, data) = distbase.http_listdir(server, HTTPS_CERT_PORT, '/%s' % path) except Exception as err: errors.append('%s: %s' % (server, err)) continue if not status: break (code, _) = distbase.close_session(path, 'READ') __reraise_errors(errors) __raise_status_errors(status, data) return eval(data.strip())
def stat(path, _flags='L'): """remote version of operation with same name""" errors = [] (code, servers_string) = distbase.open_session(path, 'READ') if code: raise OSError('code %s - %s' % (code, servers_string)) for server in servers_string.split(' '): try: (status, data) = distbase.http_stat(server, HTTPS_CERT_PORT, '/%s' % path, _flags) except Exception as err: errors.append('%s: %s' % (server, err)) continue if not status: break print('DEBUG: warning stat %s at %s failed: %s %s' % (path, server, status, data)) (code, _) = distbase.close_session(path, 'READ') __reraise_errors(errors) __raise_status_errors(status, data) stat_tuple = eval(data.strip()) return __stat_wrapper(stat_tuple)
def __close_remote_file(self, path): """Tell the current leader to close the active session for file with supplied path. """ return distbase.close_session(path, self.session_type)