折腾:
【未解决】Fabric 2中如何实现Fabric 1中的rsync_project去实现同步代码以实现项目代码部署
期间,需要去搞清楚,对于Fabric 2来说,如何分清楚,对于要运行的命令,是属于本地,还是在线的远端服务器中的。
对于run,去看:
run(command, **kwargs) Execute a shell command on the remote end of this connection. This method wraps an SSH-capable implementation of invoke.runners.Runner.run; see its documentation for details.
是在remote端,去执行shell命令,内部是通过SSH。
对于具体用法,再去看:
“run(command, **kwargs)
Execute command, returning an instance of Result.”
是针对于当前的实例去执行命令,返回结果。
而实例中,有个当前的上下文context,所有的参数,都是传入context的
然后再去看看参数解释
- warn:True还是False,当出现警告时,是否继续
一点点去搞清楚:
from fabric.api import local, lcd def lsfab(): with lcd('~/tmp/fab'): local('ls')
看了:
感觉好像是:
对于task,传入了context,就是本地环境local的
所以本地的命令,可以用context去操作
另外Connection到remote后,接着去cd,ls等操作,都针对于远程服务器的了
目前是通过:
from invoke import task from fabric import Connection RemoteHost = 'x.x.x.x' RemoteUser = 'xxx' RemotePathRoot = '/root/xxx_20180101/nlp/test_fabric' def seperatorLine(seperatorChar='-', count=80): print(seperatorChar * count) @task def deploy(context): print("deploy: context=%s", context) remoteConn = Connection(host=RemoteHost, user=RemoteUser) seperatorLine() print("Following command run in local:") context.run('pwd') # context.run('ls') seperatorLine() print("Following command run in remote server:") remoteConn.run('uname -a') remoteConn.run('pwd') remoteConn.run('ls') # with remoteConn.run('cd %s' % RemotePathRoot): # remoteConn.run('pwd', echo=True) # # remoteConn.run('ls') # remoteConn.run('ls -lha') remoteConn.run('cd %s && pwd && ls -lha' % RemotePathRoot) # remoteConn.run('ls') putFileResult = remoteConn.put('fabfile.py', remote=RemotePathRoot) print("Uploaded {0.local} to {0.remote}".format(putFileResult))
运行得到结果:
➜ Downloads fab deploy ('deploy: context=%s', <Context: <Config: {'tasks': {'search_root': None, 'collection_name': 'fabfile', 'dedupe': True, 'auto_dash_names': True}, 'run': {'shell': '/bin/bash', 'hide': None, 'pty': False, 'encoding': None, 'in_stream': None, 'replace_env': True, 'echo': False, 'warn': False, 'echo_stdin': None, 'watchers': [], 'env': {}, 'out_stream': None, 'err_stream': None, 'fallback': True}, 'timeouts': {'connect': None}, 'sudo': {'password': None, 'prompt': '[sudo] password: ', 'user': None}, 'inline_ssh_env': False, 'port': 22, 'load_ssh_configs': True, 'user': 'crifan', 'ssh_config_path': None, 'connect_kwargs': {}, 'forward_agent': False, 'gateway': None, 'runners': {'remote': <class 'fabric.runners.Remote'>, 'local': <class 'invoke.runners.Local'>}}>>) -------------------------------------------------------------------------------- Following command run in local: /Users/crifan/Downloads -------------------------------------------------------------------------------- Following command run in remote server: Linux xxx-general-01 3.10.0-693.21.1.el7.x86_64 #1 SMP Wed Mar 7 19:03:37 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux /root miniconda3 mongod.te xxx_20180101 sql tmp users.txt /root/xxx_20180101/nlp/test_fabric total 12K drwxr-xr-x 2 root root 4.0K Aug 17 13:56 . drwxr-xr-x 5 root root 4.0K Aug 17 13:52 .. -rw-r--r-- 1 root root 3.0K Aug 17 17:14 fabfile.py Uploaded /Users/crifan/Downloads/fabfile.py to /root/xxx_20180101/nlp/test_fabric/fabfile.py
其中的task传入的context,去run,感觉就是local的命令
而Connection到远端服务器后,得到的remoteConn,去run,就是remote的。
另外自己试了试:
@task def deploy(context): print("deploy: context=%s", context) remoteConn = Connection(host=RemoteHost, user=RemoteUser) # print(remoteConn) seperatorLine() ctxRunners = context.runners local = context.runners["local"] remote = context.runners["remote"] print("ctxRunners=%s, local=%s, remote=%s" % (ctxRunners, local, remote)) local.run("pwd") remote.run("pwd")
会报错:
➜ Downloads fab deploy ('deploy: context=%s', <Context: <Config: {'tasks': {'search_root': None, 'collection_name': 'fabfile', 'dedupe': True, 'auto_dash_names': True}, 'run': {'shell': '/bin/bash', 'hide': None, 'pty': False, 'encoding': None, 'in_stream': None, 'replace_env': True, 'echo': False, 'warn': False, 'echo_stdin': None, 'watchers': [], 'env': {}, 'out_stream': None, 'err_stream': None, 'fallback': True}, 'timeouts': {'connect': None}, 'sudo': {'password': None, 'prompt': '[sudo] password: ', 'user': None}, 'inline_ssh_env': False, 'port': 22, 'load_ssh_configs': True, 'user': 'crifan', 'ssh_config_path': None, 'connect_kwargs': {}, 'forward_agent': False, 'gateway': None, 'runners': {'remote': <class 'fabric.runners.Remote'>, 'local': <class 'invoke.runners.Local'>}}>>) -------------------------------------------------------------------------------- ctxRunners=<DataProxy: {'remote': <class 'fabric.runners.Remote'>, 'local': <class 'invoke.runners.Local'>}>, local=<class 'invoke.runners.Local'>, remote=<class 'fabric.runners.Remote'> Traceback (most recent call last): File "/Users/crifan/Library/Python/2.7/bin/fab", line 11, in <module> sys.exit(program.run()) File "/Users/crifan/Library/Python/2.7/lib/python/site-packages/invoke/program.py", line 335, in run self.execute() File "/Users/crifan/Library/Python/2.7/lib/python/site-packages/invoke/program.py", line 491, in execute executor.execute(*self.tasks) File "/Users/crifan/Library/Python/2.7/lib/python/site-packages/invoke/executor.py", line 129, in execute result = call.task(*args, **call.kwargs) File "/Users/crifan/Library/Python/2.7/lib/python/site-packages/invoke/tasks.py", line 128, in __call__ result = self.body(*args, **kwargs) File "/Users/crifan/Downloads/fabfile.py", line 21, in deploy local.run("pwd") TypeError: unbound method run() must be called with Local instance as first argument (got str instance instead)
看来不能通过
local的context中的runners中的local还是remote
的方式获得local,然后去run
具体原因和runners,后续再去深究。
转载请注明:在路上 » 【基本解决】Fabric 2中如何执行和调用本地和远端的命令