This is a very Fabric specific question, but more experienced python hackers might be able to answer this, even if they don't know Fabric.
I am trying to specify different behaviour in a command depending on which role it is running for, i.e.:
def restart():
if (SERVERTYPE == "APACHE"):
sudo("apache2ctl graceful",pty=True)
elif (SERVERTYPE == "APE"):
sudo("supervisorctl reload",pty=True)
I was hacking this with functions like this one:
def apache():
global SERVERTYPE
SERVERTYPE = "APACHE"
env.hosts = ['xxx.xxx.com']
But that is obviously not very elegant and I just discovered roles, so my question is:
How do I figure out which role a current instance belongs to?
env.roledefs = {
'apache': ['xxx.xxx.com'],
'APE': ['yyy.xxx.com'],
}
Thanks!
For everyone else ever with this question, here is my solution:
The key was finding env.host_string.
This is how I restart different types of servers with one command:
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)
enjoy!
I didn't test it, but might work:
def _get_current_role():
for role in env.roledefs.keys():
if env.host_string in env.roledefs[role]:
return role
return None
The env.roles
will give you the roles specified by -R flag or hardcoded in the script itself. It won't contain the roles specified per task using the command line or using @roles
decorator. There is currently no way of getting this kind of information.
The next release of fabric (1.9 probably) will provide env.effective_roles
attribute with exactly what you want - the roles being used for the currently executed task. The code for that has already been merged into master.
Have a look at this issue.
Update: Just checked the source code and it seems that this was already available as early as 1.4.2!
update 2: This seems not to work when using the @roles
decorator (in 1.5.3)! It only works when specifying the roles using the -R
command line flag.
For fabric 1.5.3 the current roles are directly available in `fabric.api.env.roles'. For example:
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
Test output on the console:
› fab -R staging testrole
[bbs-evolution.ipsw.dt.ept.lu] Executing task 'testrole'
['staging']
Done.
Or:
› 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.
With this, we can do a simple in
test in a fabric task:
@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!')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With