I have a fabfile like the following:
@hosts(\'host1\')
def host1_deploy():
\"\"\"Some logic that is specific to deploying to host1\"\"\"
@hosts(\'host2\
This is lame but it works as of Fabric 1.1.2
def host1_deploy():
"""Some logic that is specific to deploying to host1"""
if env.host in ["host1"]:
pass #this is only on host2
def host2_deploy():
"""Some logic that is specific to deploying to host2"""
if env.host in ["host2"]:
pass #this is only on host2
def deploy():
""""Deploy to both hosts, each using its own logic"""
host1_deploy()
host2_deploy()
here's my test code:
@task
@roles(["prod_web","prod_workers"])
def test_multi():
test_multi_a()
test_multi_b()
def test_multi_a():
if env.host in env.roledefs["prod_web"]:
run('uname -a')
def test_multi_b():
if env.host in env.roledefs["prod_workers"]:
run('uname -a')
Try this one. Obviously you want to replace local with run
or sudo
. The key is the empty @hosts
decorator for deploy
from fabric.api import local
from fabric.decorators import hosts
@hosts('host1')
def host1_deploy():
"""Some logic that is specific to deploying to host1"""
local('echo foo')
@hosts('host2')
def host2_deploy():
"""Some logic that is specific to deploying to host2"""
local('echo bar')
@hosts('')
def deploy():
""""Deploy to both hosts, each using its own logic"""
host1_deploy()
host2_deploy()
There's probably a better way to handle it, but you could pass both hosts to deploy(), and then in host1_deploy() and host2_deploy() check env.host:
def host1_deploy():
if env.host in ['host1']:
run(whatever1)
def host2_deploy():
if env.host in ['host2']:
run(whatever2)
@hosts('host1','host2')
def deploy():
host1_deploy()
host2_deploy()
Since Fabric 1.3, the execute
helper is now available to do just this. The documentation is available here: Intelligently executing tasks with execute.
Here is the example they use:
from fabric.api import run, roles, execute
env.roledefs = {
'db': ['db1', 'db2'],
'web': ['web1', 'web2', 'web3'],
}
@roles('db')
def migrate():
# Database stuff here.
pass
@roles('web')
def update():
# Code updates here.
pass
And then to run both migrate
and web
from another task deploy
:
def deploy():
execute(migrate)
execute(update)
And this will respect the roles and hosts lists that those tasks have.