没有找到主机的python fabric必须手动设置’env.host_string’

python fabric no host found must manually set 'env.host_string'

有没有办法让它与env.hosts一起工作?而不是每次我有多台主机运行这个时都必须手动循环?

我正在尝试使用FabricAPI,不必使用非常不方便和笨拙的Fabric命令行调用。我在一个模块/类中设置env.hosts变量,然后调用另一个类实例方法来运行fabric命令。在被调用的类实例中,我可以打印出env.hosts列表。但是当我试图运行一个命令时,它告诉我找不到主机。

如果我循环访问env.hosts数组并为env.hosts数组中的每个主机手动设置env.host变量,我就可以让run命令工作。奇怪的是,我还设置了调用类中的env.user变量,它被接收了。

例如,本工程:

1
2
3
4
5
6
    def upTest(self):
        print('env.hosts = ' + str(env.hosts))
        for host in env.hosts:
            env.host_string = host
            print('env.host_string = ' + env.host_string)
            run("uptime")

由此产生的输出:

1
2
3
4
5
env.hosts = ['ec2-....amazonaws.com']
env.host_string = ec2-....amazonaws.com
[ec2-....amazonaws.com] run: uptime
[ec2-....amazonaws.com] out:  18:21:15 up 2 days,  2:13,  1 user,  load average: 0.00, 0.01, 0.05
[ec2-....amazonaws.com] out:

这不管用…但是如果你从一个"fab"文件中运行它就可以了…对我来说毫无意义。

1
2
3
    def upTest(self):
        print('env.hosts = ' + str(env.hosts))
        run("uptime")

这是输出:

1
No hosts found. Please specify (single) host string for connection:

我确实尝试在方法上放置@task decorator(并删除"self"引用,因为decorator不喜欢这样)。但没有帮助。

有没有办法让它与env.hosts一起工作?而不是每次我有多台主机运行这个时都必须手动循环?


最后,我使用execute()和exec解决了这个问题。

主.py

1
2
3
4
5
6
7
8
#!/usr/bin/env python

from demo import FabricSupport

hosts = ['localhost']

myfab = FabricSupport()
myfab.execute("df",hosts)

演示.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/env python

from fabric.api import env, run, execute

class FabricSupport:
    def __init__(self):
        pass

    def hostname(self):
        run("hostname")

    def df(self):
        run("df -h")

    def execute(self,task,hosts):
        get_task ="task = self.%s" % task
        exec get_task
        execute(task,hosts=hosts)

python主.py

1
2
3
[localhost] Executing task 'hostname'
[localhost] run: hostname
[localhost] out: heydevops-workspace

我发现最好不要在代码中设置env.hosts,而是根据配置文件定义角色,并使用fab工具指定角色。它对我有用

我的角色.json

1
2
3
4

法布文件.py

1
2
3
4
5
6
7
8
9
10
11
12
from fabric.api import env, run, task
import json

def load_roles():
    with open('my_roles.json') as f:
        env.roledefs = json.load(f)

load_roles()

@task
def my_task():
    run("hostname")

CLI

江户十一〔一〕号

运行web1web2的每个my_task的输出都在这里。