织物的独立 fabfile?

发布于 2024-09-10 13:51:26 字数 269 浏览 6 评论 0原文

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

from fabric.api import run

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

if __name__ == '__main__':
    host_type()    

Is it possible to make the fabfile stand-alone?
I'm not very fond of running the external tool 'fab'. If I manage to get the fabfile standalone I can run the file from within the (Eclipse / Pydev) IDE, easily debug it, use project configurations and paths etc.
Why doesn't this work:

from fabric.api import run

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

if __name__ == '__main__':
    host_type()    

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

思念绕指尖 2024-09-17 13:51:26

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

from fabric.main import main

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

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

I eventually found the solution (and it is really simple!).
In my fabfile, I added:

from fabric.main import main

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

I hope this helps people...

月依秋水 2024-09-17 13:51:26

如果我没记错的话,我也无法让 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 有大量文档

If I recall correctly, I couldn't get the Fabric API to do what I wanted either. I decided to abandon the extra layer entirely and use Paramiko (the underlying SSH library used by Fabric) directly:

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()

While there are a few more steps involved, doing it this way allows you to leverage the SSH layer directly, as opposed to using subprocess to spwan another Python instance, or figuring out the Fabric API. I have several projects, both web- and console- using Paramiko in this manner and I haven't had too much trouble.

Paramiko is extensively documented.

心房敞 2024-09-17 13:51:26

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

import subprocess

def hello():
    print 'Hello'

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

This isn't a really nice solution, but will work:

import subprocess

def hello():
    print 'Hello'

if __name__ == '__main__':
    subprocess.call(['fab', '-f', __file__, 'hello'])
赴月观长安 2024-09-17 13:51:26

我将上面的示例微调为过去的 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()

I fine tuned the above example to past through argv arguments you might want to pass to local commands and specify an optional default_commands list instead of a hard coded command name. Note, the filename must have a .py extension or fab will not detect it as a fab file!

#!/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()
秋心╮凉 2024-09-17 13:51:26

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

“正如该部分提到的,关键就是 run、sudo 和其他
连接时操作仅查看一处: env.host_string 。所有的
设置主机的其他机制由 fab 工具解释
当它运行时,作为库运行时并不重要。”

当我发现这个问题时,我正在考虑同样的问题。另外,在查看时我记得提到在 fabfile 中使用时,环境更改不应该在相同的位置def as 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()

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

"As that section mentions, the key is simply that run, sudo and the other
operations only look in one place when connecting: env.host_string . All of
the other mechanisms for setting hosts are interpreted by the fab tool
when it runs, and don’t matter when running as a library."

I was looking at this same problem when I found this. Also, while looking I recall mention that when used in a fabfile, env changes should not be in the same def as run, sudo. Who knows if this still applies when used in "library" mode.

EDIT: Here is an example of said implementation

from fabric.api import env, run

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

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

if __name__ == '__main__':
    setup()
    main()
蓝天 2024-09-17 13:51:26
# 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()
# 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()
只是我以为 2024-09-17 13:51:26

1.5.0 开始,有一种比乱搞更好的方法来做到这一点argv。

import fabric.main

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

if __name__ == "__main__":
    main()

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

Since 1.5.0 there is a way better way to do this than messing around with argv.

import fabric.main

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

if __name__ == "__main__":
    main()

This can also be utilized as a console script in setup.py

故事和酒 2024-09-17 13:51:26

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

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

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

  main()

Add this to the bottom of your fab file.

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

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

  main()
梦太阳 2024-09-17 13:51:26

这是我对 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__])

This is my modified version of Greg's answer that changes default behavior to show available commands instead of listing tons of fabric options.

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__])
歌入人心 2024-09-17 13:51:26

我在 run Fabric 上间接找到了解决方案文件重命名为 fabfile.py 和无密码 ssh 以外的文件

def deploy():
    ...

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

如果您的文件没有 .py 扩展名,这种方法也有效。

I found the solution indirectly on run fabric file renamed other than fabfile.py and password-less ssh

def deploy():
    ...

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

This way also work if your file doesn't have .py extension.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文