如何动态编辑Fabric中的env.roledefs?

1 投票
1 回答
1153 浏览
提问于 2025-04-18 12:07

我查看了这个问题,但它并没有解决我的困扰。

我想做的事情是:

@task
def setEnv(environment):
    if environment == 'prod':
        env.roledefs['nginx'] = [ 'www@tnginx01', 'www@tnginx02' ]
        env.roledefs['middle'] = [ 'www@tmiddle01', 'www@tmiddle02' ]
    elif environment == 'preprod':
        env.roledefs['nginx'] = [ 'www@pnginx01', 'www@pnginx02' ]
        env.roledefs['middle'] = [ 'www@pmiddle01', 'www@pmiddle02' ]
    else:
        puts(red("This environment doesn't exist. Possible values are 'preprod' and 'prod'", True))
        sys.exit()

    env.first_middle = env.roledefs['middle'][0]

@task
@roles(env.first_middle)
def deploy():
    run('pwd')

但是看起来在Fabfile加载到内存后,无法更改env.roledefs的值。当你尝试运行 fab setEnv:prod deploy 时,它不会成功:

没有找到主机。请指定一个(单个)主机字符串以进行连接

有没有人知道怎么做到这一点?请注意,我不能用roledefs来表示环境。我已经用roledefs来存储属于同一个“集群”的服务器,而每个环境有几个集群,每个集群又有几台服务器。

1 个回答

2

我刚刚找到了解决我问题的方法。

关键是env.roledefs不能在Fabric任务内部进行编辑。所以,修改它的代码必须放在最开始在全局范围内

if env.get('env') == 'prod':
    env.roledefs['nginx'] = [ 'www@tnginx01', 'www@tnginx02' ]
    env.roledefs['middle'] = [ 'www@tmiddle01', 'www@tmiddle02' ]
elif env.get('env') == 'preprod':
    env.roledefs['nginx'] = [ 'www@pnginx01', 'www@pnginx02' ]
    env.roledefs['middle'] = [ 'www@pmiddle01', 'www@pmiddle02' ]
else:
    puts(red("This environment doesn't exist. Possible values are 'preprod' and 'prod'", True))
    sys.exit()

    env.first_middle = env.roledefs['middle'][0]

@task
@roles(env.first_middle)
def deploy():
    run('pwd')

然后我就这样调用fabfile:

fab --set env=preprod deploy

我的答案受到这个链接的启发,给了我这个想法。

撰写回答