折腾:
【未解决】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中如何执行和调用本地和远端的命令