9

是否可以使 fabfile 独立?
我不太喜欢运行外部工具“fab”。如果我设法获得独立的 fabfile,我可以从(Eclipse / Pydev)IDE 中运行该文件,轻松调试它,使用项目配置和路径等。
为什么这不起作用:

from fabric.api import run

def host_type():
    run('uname -s')

if __name__ == '__main__':
    host_type()    
4

10 回答 10

14

我最终找到了解决方案(这真的很简单!)。
在我的 fabfile 中,我添加了:

from fabric.main import main

if __name__ == '__main__':
    import sys
    sys.argv = ['fab', '-f', __file__, 'update_server']
    main()

我希望这可以帮助人们...

于 2011-06-19T08:58:56.503 回答
3

如果我没记错的话,我也无法让 Fabric API 做我想做的事。我决定完全放弃额外的层,直接使用Paramiko(Fabric 使用的底层 SSH 库):

import os
import paramiko

ssh = paramiko.SSHClient()
ssh.load_system_host_keys()
ssh.load_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('hostname.example.com', 22, 'username', 'password')
ssh.save_host_keys(os.path.expanduser('~/.ssh/known_hosts'))
stdin, stdout, stderr = ssh.exec_command('uname -s')
print stdout.read()

虽然涉及更多步骤,但这样做可以让您直接利用 SSH 层,而不是使用subprocess生成另一个 Python 实例或找出 Fabric API。我有几个项目,包括 web 和控制台,都以这种方式使用 Paramiko,我没有遇到太多麻烦。

Paramiko 被广泛记录

于 2010-07-19T07:26:43.340 回答
2

1.5.0开始,有一种比乱用 argv 更好的方法。

import fabric.main

def main():
    fabric.main.main(fabfile_locations=[__file__])

if __name__ == "__main__":
    main()

这也可以用作 setup.py 中的控制台脚本

于 2013-08-22T00:59:41.393 回答
2

docs.fabfile.org/en/1.4.0/usage/library.html

“正如那部分提到的,关键是运行、sudo 和其他操作在连接时只在一个地方查找: env.host_string 。所有其他设置主机的机制都由 fab 工具在运行时解释,并且不要作为图书馆运行时没关系。”

当我发现这个时,我正在寻找同样的问题。另外,在查看时我记得提到在 fabfile 中使用时,env 更改不应与 run、sudo 位于相同的 def 中。谁知道在“库”模式下使用时这是否仍然适用。

编辑:这是上述实现的一个例子

from fabric.api import env, run

def main():
    run("uname -a")

def setup():
    env.host_string = "me@remoteHost"

if __name__ == '__main__':
    setup()
    main()
于 2012-02-23T05:36:51.833 回答
2
# thanks to aaron, extending his code a little more
# here is a little bit more of a graceful solution than running subprocess.call, and specifying multiple hosts

from fabric.api import env, run

def main():
    run("uname -a")

def setup():
    env.hosts = ['host0','host1']

if __name__ == '__main__':
    setup()
    for host in env.hosts:
        env.host_string = host
        main()
于 2012-05-25T22:42:46.727 回答
2

我对上面的示例进行了微调,以通过 argv 参数传递给本地命令,并指定一个可选的 default_commands 列表而不是硬编码的命令名称。请注意,文件名必须具有 .py 扩展名,否则 fab 不会将其检测为 fab 文件!

#!/usr/bin/env python
from fabric.api import local

default_commands = ['hello', ]

def hello():
    print ('hello world')

def hostname():
    local('hostname')

if __name__ == '__main__':
   import sys
   from fabric.main import main
   sys.argv = ['fab', '-f', __file__,] +  default_commands + sys.argv[1:]
   main()
于 2012-01-12T17:01:08.567 回答
2

这不是一个很好的解决方案,但会起作用:

import subprocess

def hello():
    print 'Hello'

if __name__ == '__main__':
    subprocess.call(['fab', '-f', __file__, 'hello'])
于 2010-07-19T06:39:52.323 回答
1

将此添加到您的 fab 文件的底部。

if __name__ == '__main__':
  from fabric.main import main
  import sys

  sys.argv = ['fab', '-f', __file__] + sys.argv[1:]

  main()
于 2013-01-12T00:50:39.133 回答
0

这是我对Greg 答案的修改版本,它更改了默认行为以显示可用命令,而不是列出大量的结构选项。

if __name__ == '__main__':
    # imports for standalone mode only
    import sys, fabric.main

    # show available commands by default
    if not sys.argv[1:]:
        sys.argv.append('--list')

    fabric.main.main(fabfile_locations=[__file__])
于 2014-04-21T10:26:33.727 回答
0

我在运行结构文件上间接找到了解决方案,而不是 fabfile.py 和无密码 ssh

def deploy():
    ...

if __name__ == '__main__':
    from fabric import execute
    execute(deploy)

如果您的文件没有.py扩展名,这种方式也可以工作。

于 2015-10-01T08:34:32.117 回答