我们学习了defer了实例,现在我们来写个基于paramiko的异步连接服务器的代码
#!/usr/bin/python # -*- coding:cp936 -*- from optparse import OptionParser import paramiko from twisted.internet import reactor, defer parser = OptionParser(usage="%prog",version="version %prog 1.0.0") parser.add_option("-f", "--files",action="store", type="string", dest="files", help="give the file's name") (options, args) = parser.parse_args() class UPDATE: def __init__(self,hostname,username,password): self.hostname = hostname self.username = username self.password = password def update(self): paramiko.util.log_to_file('/tmp/update.log') s=paramiko.SSHClient() s.set_missing_host_key_policy(paramiko.AutoAddPolicy()) try: s.connect(hostname=self.hostname,username=self.username,password=self.password) stdin,stdout,stderr=s.exec_command('cd /opt;tar xvf %s;' %options.files.split('/')[-1]) except Exception as e: return '%s %s' %(self.hostname,e) result=stdout.read() s.close() return '%s %s' %(self.hostname,result.strip('\n')) def transport(self): try: t=paramiko.Transport((self.hostname,22)) # mykey = paramiko.RSAKey.from_private_key_file(rsakey,password='jastme') #use key # t.connect(user,mykey) t.connect(username=self.username,password=self.password) sftp=paramiko.SFTPClient.from_transport(t) sftp.put('/root/%s' %(options.files.split('/')[-1]),'/opt/%s' %(options.files.split('/')[-1]),confirm=True) except Exception as e: return '%s %s' %(self.hostname,e) sftp.close() return 'Copy files %s to %s Sucessed' %(options.files.split('/')[-1],self.hostname) def updatedf(hostname,username,password): d=defer.Deferred() reactor.callLater(1,d.callback,UPDATE(hostname,username,password).update()) return d def transportdf(hostname,username,password): d=defer.Deferred() reactor.callLater(1,d.callback,UPDATE(hostname,username,password).transport()) return d def printData(x): print x if __name__ == '__main__': serverlist=['192.168.16.102','192.168.16.209'] input=raw_input("1. 推送文件到服务器\n2. 更新\n3. 推送文件后更新\n") if input == '1': for server in serverlist: dt=transportdf(server,'root','pass') dt.addCallback(printData) elif input == '2': for server in serverlist: du=updatedf(server,'root','pass') du.addCallback(printData) elif input == '3': for server in serverlist: dt=transportdf(server,'root','pass') dt.addCallback(printData) du=updatedf(server,'root','pass') du.addCallback(printData) reactor.callLater(1, reactor.stop) reactor.run()
这是一个远程连接服务器,推送文件,使用命令解压包的程序(当然,我们还可以做很多扩展,可以把它写成一个自动化更新服务器的代码)。我们用callback来回调paramiko的函数。看过前面章节的朋友应该很容易读懂这个代码。
在这个代码,我们使用的try来避免抛出错误后代码异常退出的情况,利用execpt来返回错误,从而充分的利用callback来回调这些信息。