class SwiftFTPShell: """ Implements all the methods needed to treat Swift as an FTP Shell """ implements(IFTPShell) def __init__(self, swiftconn): self.swiftconn = swiftconn self.swiftfilesystem = SwiftFileSystem(self.swiftconn) self.log_command('login') def log_command(self, command, *args): arg_list = ', '.join(str(arg) for arg in args) log.msg("COMMAND: %s(%s)" % (command, arg_list), system="SwFTP-FTP, (%s)" % self.swiftconn.username, metric='command.%s' % command) def logout(self): self.log_command('logout') def _fullpath(self, path_parts): return '/'.join(path_parts) def makeDirectory(self, path): self.log_command('makeDirectory', path) fullpath = self._fullpath(path) return self.swiftfilesystem.makeDirectory(fullpath) def removeDirectory(self, path): self.log_command('removeDirectory', path) fullpath = self._fullpath(path) def not_found_eb(failure): failure.trap(NotFound) def conflict_eb(failure): failure.trap(Conflict) raise CmdNotImplementedForArgError( 'Cannot delete non-empty directories.') d = self.swiftfilesystem.removeDirectory(fullpath) d.addErrback(not_found_eb) d.addErrback(conflict_eb) return d def removeFile(self, path): self.log_command('removeFile', path) fullpath = self._fullpath(path) def errback(failure): failure.trap(NotFound) d = self.swiftfilesystem.removeFile(fullpath) d.addErrback(errback) return d def rename(self, fromPath, toPath): self.log_command('rename', fromPath, toPath) oldpath = self._fullpath(fromPath) newpath = self._fullpath(toPath) d = self.swiftfilesystem.renameFile(oldpath, newpath) def errback(failure): failure.trap(NotFound, Conflict, NotImplementedError) if failure.check(NotFound): return defer.fail(FileNotFoundError(oldpath)) else: return defer.fail(CmdNotImplementedForArgError(oldpath)) d.addErrback(errback) return d def access(self, path): self.log_command('access', path) fullpath = self._fullpath(path) d = self.swiftfilesystem.getAttrs(fullpath) def cb(result): if result['content_type'] == 'application/directory': return defer.succeed(lambda: None) return defer.fail(IsNotADirectoryError(fullpath)) d.addCallback(cb) def err(failure): failure.trap(NotFound) # Containers need to actually exist before uploading anything # inside of them. Therefore require containers to actually exist. # All other paths don't have to. if len(path) != 1: return defer.succeed(lambda: None) else: return defer.fail(IsNotADirectoryError(fullpath)) d.addErrback(err) return d def stat(self, path, keys=()): self.log_command('stat', path, keys) fullpath = self._fullpath(path) def cb(result): return stat_format(keys, result) def err(failure): failure.trap(NotFound) return defer.fail(FileNotFoundError(fullpath)) d = self.swiftfilesystem.getAttrs(fullpath) d.addCallback(cb) d.addErrback(err) return d def list(self, path=None, keys=()): self.log_command('list', path) fullpath = self._fullpath(path) def cb(results): l = [] for key, value in results.iteritems(): l.append([key, stat_format(keys, value)]) return l def err(failure): failure.trap(NotFound) return defer.fail(FileNotFoundError(fullpath)) d = self.swiftfilesystem.get_full_listing(fullpath) d.addCallback(cb) d.addErrback(err) return d def openForReading(self, path): self.log_command('openForReading', path) fullpath = self._fullpath(path) def cb(results): return SwiftReadFile(self.swiftfilesystem, fullpath) def err(failure): failure.trap(NotFound) return defer.fail(FileNotFoundError(fullpath)) try: d = self.swiftfilesystem.checkFileExistance(fullpath) d.addCallback(cb) d.addErrback(err) return d except NotImplementedError: return defer.fail(IsADirectoryError(fullpath)) def openForWriting(self, path): self.log_command('openForWriting', path) fullpath = self._fullpath(path) container, obj = obj_to_path(fullpath) if not container or not obj: log.msg('cannot upload to root') raise CmdNotImplementedForArgError( 'Cannot upload files to root directory.') f = SwiftWriteFile(self.swiftfilesystem, fullpath) return defer.succeed(f)
class SwiftFTPShell(object): """ Implements all the methods needed to treat Swift as an FTP Shell """ implements(IFTPShell) def __init__(self, swiftconn, rabbitmq_cluster, queue_name): self.swiftconn = swiftconn self.swiftfilesystem = SwiftFileSystem(self.swiftconn) self.log_command('login') self.rabbitmq_cluster = rabbitmq_cluster self.queue_name = queue_name def log_command(self, command, *args): arg_list = ', '.join(str(arg) for arg in args) msg("cmd: %s(%s)" % (command, arg_list), system="SwFTP-FTP, (%s)" % self.swiftconn.username, metric='command.%s' % command) def username(self): return self.swiftconn.username def logout(self): self.log_command('logout') if self.swiftconn.pool: self.swiftconn.pool.closeCachedConnections() del self.swiftconn def _fullpath(self, path_parts): return '/'.join(path_parts) def makeDirectory(self, path): self.log_command('makeDirectory', path) fullpath = self._fullpath(path) return self.swiftfilesystem.makeDirectory(fullpath) def removeDirectory(self, path): self.log_command('removeDirectory', path) fullpath = self._fullpath(path) def not_found_eb(failure): failure.trap(NotFound) def conflict_eb(failure): failure.trap(Conflict) raise CmdNotImplementedForArgError( 'Cannot delete non-empty directories.') d = self.swiftfilesystem.removeDirectory(fullpath) d.addErrback(not_found_eb) d.addErrback(conflict_eb) return d def removeFile(self, path): self.log_command('removeFile', path) fullpath = self._fullpath(path) def errback(failure): failure.trap(NotFound, NotImplementedError) if failure.check(NotImplementedError): return defer.fail(IsADirectoryError(fullpath)) d = defer.maybeDeferred(self.swiftfilesystem.removeFile, fullpath) d.addErrback(errback) return d def rename(self, fromPath, toPath): self.log_command('rename', fromPath, toPath) oldpath = self._fullpath(fromPath) newpath = self._fullpath(toPath) d = self.swiftfilesystem.renameFile(oldpath, newpath) def errback(failure): failure.trap(NotFound, Conflict, NotImplementedError) if failure.check(NotFound): return defer.fail(FileNotFoundError(oldpath)) else: return defer.fail(CmdNotImplementedForArgError(oldpath)) d.addErrback(errback) return d def access(self, path): self.log_command('access', path) fullpath = self._fullpath(path) d = self.swiftfilesystem.getAttrs(fullpath) def cb(result): if result['content_type'] == 'application/directory': return defer.succeed(lambda: None) return defer.fail(IsNotADirectoryError(fullpath)) d.addCallback(cb) def err(failure): failure.trap(NotFound) # Containers need to actually exist before uploading anything # inside of them. Therefore require containers to actually exist. # All other paths don't have to. if len(path) != 1: return defer.succeed(lambda: None) else: return defer.fail(IsNotADirectoryError(fullpath)) d.addErrback(err) return d def stat(self, path, keys=()): self.log_command('stat', path, keys) fullpath = self._fullpath(path) def cb(result): return stat_format(keys, result) def err(failure): failure.trap(NotFound) return defer.fail(FileNotFoundError(fullpath)) d = self.swiftfilesystem.getAttrs(fullpath) d.addCallback(cb) d.addErrback(err) return d def list(self, path=None, keys=()): self.log_command('list', path) fullpath = self._fullpath(path) def cb(results): l = [] for key, value in results.iteritems(): l.append([key, stat_format(keys, value)]) return l def err(failure): failure.trap(NotFound) return defer.fail(FileNotFoundError(fullpath)) d = self.swiftfilesystem.get_full_listing(fullpath) d.addCallback(cb) d.addErrback(err) return d def openForReading(self, path): self.log_command('openForReading', path) fullpath = self._fullpath(path) def cb(results): return SwiftReadFile(self.swiftfilesystem, fullpath) def err(failure): failure.trap(NotFound) return defer.fail(FileNotFoundError(fullpath)) try: d = self.swiftfilesystem.checkFileExistance(fullpath) d.addCallback(cb) d.addErrback(err) return d except NotImplementedError: return defer.fail(IsADirectoryError(fullpath)) def openForWriting(self, path): self.log_command('openForWriting', path) fullpath = self._fullpath(path) container, obj = obj_to_path(fullpath) if not container or not obj: raise CmdNotImplementedForArgError( 'Cannot upload files to root directory.') f = SwiftWriteFile(self.swiftfilesystem, fullpath,\ self.rabbitmq_cluster, self.queue_name) return defer.succeed(f)