最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【基本解决】Fabric 2中如何执行和调用本地和远端的命令

执行 crifan 1393浏览 0评论
折腾:
【未解决】Fabric 2中如何实现Fabric 1中的rsync_project去实现同步代码以实现项目代码部署
期间,需要去搞清楚,对于Fabric 2来说,如何分清楚,对于要运行的命令,是属于本地,还是在线的远端服务器中的。
对于run,去看:
http://docs.fabfile.org/en/2.3/api/connection.html#fabric.connection.Connection.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。
对于具体用法,再去看:
http://docs.pyinvoke.org/en/latest/api/runners.html#invoke.runners.Runner.run
“run(command, **kwargs)
Execute command, returning an instance of Result.”
是针对于当前的实例去执行命令,返回结果。
而实例中,有个当前的上下文context,所有的参数,都是传入context的
然后再去看看参数解释
  • warn:True还是False,当出现警告时,是否继续
一点点去搞清楚:
Python fabric实现远程操作和部署
from fabric.api import local, lcd

def lsfab():
    with lcd('~/tmp/fab'):
        local('ls')
看了:
http://www.fabfile.org/upgrading.html#general
感觉好像是:
对于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中如何执行和调用本地和远端的命令

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
80 queries in 0.187 seconds, using 22.15MB memory