面料的独立fabfile?

时间:2010-07-19 06:31:13

标签: python fabric

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

from fabric.api import run

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

if __name__ == '__main__':
    host_type()    

10 个答案:

答案 0 :(得分:13)

我最终找到了解决方案(而且非常简单!) 在我的fabfile中,我补充道:

from fabric.main import main

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

我希望这有助于人们......

答案 1 :(得分: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。我有几个项目,包括网络和控制台 - 以这种方式使用Paramiko,我没有遇到太多麻烦。

Paramiko是extensively documented

答案 2 :(得分:2)

这不是一个非常好的解决方案,但可行:

import subprocess

def hello():
    print 'Hello'

if __name__ == '__main__':
    subprocess.call(['fab', '-f', __file__, 'hello'])

答案 3 :(得分: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()

答案 4 :(得分:2)

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

“正如该部分提到的那样,关键在于运行,sudo和其他 连接时,操作只在一个地方查找:env.host_string。所有的 用于设置主机的其他机制由fab工具解释 当它运行时,在作为库运行时无所谓。“

当我发现这个时,我正在看同样的问题。此外,虽然看起来我记得提到,当在fabfile中使用时,env更改不应该与run,sudo相同。谁知道在“库”模式下使用时是否仍然适用。

编辑:以下是所述实施的一个例子

from fabric.api import env, run

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

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

if __name__ == '__main__':
    setup()
    main()

答案 5 :(得分: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()

答案 6 :(得分:2)

1.5.0以来,有一种更好的方法可以做到这一点,而不是乱搞argv。

import fabric.main

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

if __name__ == "__main__":
    main()

这也可以用作setup.py

中的控制台脚本

答案 7 :(得分:1)

将其添加到fab文件的底部。

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

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

  main()

答案 8 :(得分:0)

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

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__])

答案 9 :(得分:0)

我间接在run fabric file renamed other than fabfile.py and password-less ssh

找到了解决方案
def deploy():
    ...

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

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