如何在Python Fabric中发现当前角色
这是一个非常关于Fabric的问题,不过有经验的Python高手可能也能回答,即使他们不熟悉Fabric。
我想根据命令运行的角色来指定不同的行为,也就是说:
def restart():
if (SERVERTYPE == "APACHE"):
sudo("apache2ctl graceful",pty=True)
elif (SERVERTYPE == "APE"):
sudo("supervisorctl reload",pty=True)
我之前用这样的函数来处理这个问题:
def apache():
global SERVERTYPE
SERVERTYPE = "APACHE"
env.hosts = ['xxx.xxx.com']
但这样显然不太优雅,而且我刚发现了角色的概念,所以我想问:
我怎么才能知道当前实例属于哪个角色呢?
env.roledefs = {
'apache': ['xxx.xxx.com'],
'APE': ['yyy.xxx.com'],
}
谢谢!
5 个回答
12
我没有测试过,但可能可以用:
def _get_current_role():
for role in env.roledefs.keys():
if env.host_string in env.roledefs[role]:
return role
return None
18
对于所有有这个问题的人,这里是我的解决办法:
关键在于找到 env.host_string。
这样我就可以用一个命令重启不同类型的服务器:
env.roledefs = {
'apache': ['xxx.xxx.com'],
'APE': ['yyy.xxx.com']
}
def apache():
env.roles = ['apache']
...
def restart():
if env.host_string in env.roledefs['apache']:
sudo("apache2ctl graceful", pty=True)
elif env.host_string in env.roledefs['APE']:
sudo ("supervisorctl reload", pty=True)
希望你喜欢!
5
更新: 刚刚查看了 源代码,发现这个功能早在 1.4.2 版本就已经有了!
更新 2: 在使用 @roles
装饰器时(在 1.5.3 版本),这个功能似乎不好使! 只有在命令行中使用 -R
参数时才有效。
在 fabric 1.5.3 版本中,当前的角色可以直接在 `fabric.api.env.roles` 中找到。例如:
import fabric.api as fab
fab.env.roledefs['staging'] = ['bbs-evolution.ipsw.dt.ept.lu']
fab.env.roledefs['prod'] = ['bbs-arbiter.ipsw.dt.ept.lu']
@fab.task
def testrole():
print fab.env.roles
在控制台上的测试输出:
› fab -R staging testrole
[bbs-evolution.ipsw.dt.ept.lu] Executing task 'testrole'
['staging']
Done.
或者:
› fab -R staging,prod testrole
[bbs-evolution.ipsw.dt.ept.lu] Executing task 'testrole'
['staging', 'prod']
[bbs-arbiter.ipsw.dt.ept.lu] Executing task 'testrole'
['staging', 'prod']
Done.
通过这个,我们可以在 fabric 任务中做一个简单的 in
测试:
@fab.task
def testrole():
if 'prod' in fab.env.roles:
do_production_stuff()
elif 'staging' in fab.env.roles:
do_staging_stuff()
else:
raise ValueError('No valid role specified!')