fab-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Fab-user] Task.run() and task decorators


From: Rich Andrews
Subject: [Fab-user] Task.run() and task decorators
Date: Sun, 15 Dec 2013 14:55:32 -0500

Hello, some guidance would be greatly appreciated.  My difficulty is understanding the design intention with fab.api.Task subclasses.    It appears that a reasonable pattern is to subclass Task, and implement task-oriented logic in Task.run().  One would then be left with a reusable Task subclass that may be used with a variety of @tasks.

For example, should a Task subclass be made that implements some task-oriented logic in run(), it is believed that the Task would then be utilized as follows:

@task(task_class=CustomTask, myarg='value_a', alias='ata')
def wrapped_function_a(instance):
    # logic is in CustomTask.run()
    pass

@task(task_class=CustomTask, myarg='value_b', alias='ata')
def wrapped_function_b(instance):
    # logic is in CustomTask.run()
    pass

Then, CustomTask is instantiated once for each declared @task decorator, and customtask.run() is called by the fab runtime with the custom args in @task and then for each host in the specified role.  For example, fab ... -H a,b,c,d would result in four runs of customtask.run()

The desire is that a decorator such as @runs_once could then be stacked.  But what happens in this case is that the customtask.run() is invoked for each host specified in the role, and the wrapped function is what runs once.

Is there another preferred way to invoke Task subclasses? Or does the task-oriented logic belong in the function wrapped by @task?

If the behavior described ins't clear, a runnable code example and output is available below.

Thanks!

--


Python 2.7.4
Fabric 1.8.0
Paramiko 1.12.0

fab_busybox1.py:

#!/bin/env python

from fabric.api import *
from fabric.tasks import Task

class CustomTask(Task):
    # init once for all tasks name this class via task_class
    def __init__(self, func, myarg, *args, **kwargs):
        super(CustomTask, self).__init__(*args, **kwargs)
        self.func = func
        self.myarg = myarg

    # run multiple times for all hosts in roles
    def run(self, *args, **kwargs):
        print("%s run()" % self)
        return self.func(self, *args, **kwargs)

@task(task_class=CustomTask, myarg='value', alias='at')
@runs_once
def wrapped_custom_task(instance):
    print("wrapped_custom_task()")


$ fab -f fab_busybox1.py -H a,b,c,d at
[a] Executing task 'at'
<fab_busybox1.CustomTask object at 0x99fdccc> run()
wrapped_custom_task()
[b] Executing task 'at'
<fab_busybox1.CustomTask object at 0x99fdccc> run()
[c] Executing task 'at'
<fab_busybox1.CustomTask object at 0x99fdccc> run()
[d] Executing task 'at'
<fab_busybox1.CustomTask object at 0x99fdccc> run()





reply via email to

[Prev in Thread] Current Thread [Next in Thread]