Search code examples
fabriccontinuous-deliveryautodeploy

How to have some Fabric tasks only run once locally while others run on all hosts


In my fabric scripts I have the following problem. I have a main task called autodeploy. Within this task I have some tasks that I only want to run once, locally. all remote tasks should run on each of the hosts of the host list.

env.roledefs ={
  'testing': ['t-server-01', 't-server-02']  
  'staging': ['s-server-01', 's-server-02']  
  'live': ['l-server-01', 'l-server-02']  
}

def localtask1():
  # download artifact

def localtask2(): 
  # cleanup locally

def remotetask():
  # deploy artifact to all hosts

def autodeploy():
  localtask1() # run this task only once, locally  

  remotetask() # run this task on all hosts

  localtask2() # run this task only once

The call is the following. I want to pass the role as an attribute.

fab -R test autodeploy

Solution

  • Use the execute function inside the wrapper function autodeploy, and specify a host list for the remote task.

    For the other two you can call them with execute, like for the remote task, or directly. Use the local function inside them and you'll be fine, and not need to have ssh on localhost.

    Docs are here for how best ot use the new execute function.

    EDIT

    Since you mention a different use case in the comments I'll mock up how you'd do that, from bits in the documentation given already, adding the param passing section

    code:

    #copy above
    
    #redefine this one
    def autodeploy(role_from_arg):
        localtask1()
        execute(remotetask, role=role_from_arg)
        localtask2()
    
    #calls like fab autodeploy:testing