Question

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
Was it helpful?

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

OTHER TIPS

Use the runs_once decorator.

@runs_once
def localtask1():
    local('command')

You can abuse the hosts decorator to force a single task to run once only, by specifying "localhost" as the host.

Example:

@fabric.decorators.hosts("localhost")
def localtask1():
    # download artefact
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top