The following fabfile.py allows you to define some tasks to run on "master" hosts and some on "slave" hosts. You can then vary which hosts apply to these roles by using "prod" or "stage" to define env.roledefs when fabfile.py is imported. Below I demonstrate using different command line syntaxes to accomplish the same thing, either `-R <role>` or `--set de=<role>` or using a task `<role>`. I've used all 3 of these syntaxes in various fabfiles, depending on my mood the day I wrote them. Personally I would avoid using `-R` to define `env.roledefs`, since they already have a different semantic association.
from fabric.api import *
# Using -R to set roledefs
if 'prod' in env.roles:
env.roledefs = {'master': ['host1'], 'slave': ['host2', 'host3']}
elif 'stage' in env.roles:
env.roledefs = {'master': ['host4'], 'slave': ['host5', 'host6']}
# Using --set to set roledefs
if env.get('de') == 'prod':
env.roledefs = {'master': ['host1'], 'slave': ['host2', 'host3']}
elif env.get('de') == 'stage':
env.roledefs = {'master': ['host4'], 'slave': ['host5', 'host6']}
# Using tasks to set roledefs
@task
def prod():
env.roledefs = {'master': ['host1'], 'slave': ['host2', 'host3']}
@task
def stage():
env.roledefs = {'master': ['host4'], 'slave': ['host5', 'host6']}
# Roles to be executed on different sets of hosts
@roles('master')
@task
def do_master():
print env.host_string
@roles('slave')
@task
def do_slave():
print env.host_string
Here you can see that the effect is the same no matter which command line syntax you use (though your edge cases might vary):
$ fab --set de=prod do_master do_slave
[host1] Executing task 'do_master'
host1
[host2] Executing task 'do_slave'
host2
[host3] Executing task 'do_slave'
host3
Done.
$ fab --set de=stage do_master do_slave
[host4] Executing task 'do_master'
host4
[host5] Executing task 'do_slave'
host5
[host6] Executing task 'do_slave'
host6
Done.
$ fab -R prod do_master do_slave
[host1] Executing task 'do_master'
host1
[host2] Executing task 'do_slave'
host2
[host3] Executing task 'do_slave'
host3
Done.
$ fab -R stage do_master do_slave
[host4] Executing task 'do_master'
host4
[host5] Executing task 'do_slave'
host5
[host6] Executing task 'do_slave'
host6
Done.
$ fab prod do_master do_slave
[host1] Executing task 'do_master'
host1
[host2] Executing task 'do_slave'
host2
[host3] Executing task 'do_slave'
host3
Done.
$ fab stage do_master do_slave
[host4] Executing task 'do_master'
host4
[host5] Executing task 'do_slave'
host5
[host6] Executing task 'do_slave'
host6
Done.