是否有可能使fabfile独立?
我不太喜欢运行外部工具'fab'。如果我设法将fabfile独立运行,我可以在(Eclipse / Pydev)IDE中运行该文件,轻松调试它,使用项目配置和路径等。
为什么这不起作用:
from fabric.api import run
def host_type():
run('uname -s')
if __name__ == '__main__':
host_type()
答案 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
扩展名,这种方式也可以。