关于python:如何动态编辑Fabric中的env.roledefs?

How to dynamically edit env.roledefs in Fabric?

我查过这个问题,但它不能回答我的问题。

我想做如下的事情:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@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时,它将不起作用:

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

有人知道怎么做吗?请注意,我不能使用roledefs来表示环境。我已经使用roledefs来存储属于同一个"集群"的服务器,并且每个环境都有多个带有多个服务器的集群。


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

关键是不能从结构任务中编辑env.roledefs。因此,代码编辑必须在全局范围内处于开始阶段。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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:

1
fab --set env=preprod deploy

我的回答是从这个给我灵感的链接中得到的。