Skip to content
thiell edited this page Mar 4, 2012 · 3 revisions

Task

Introduction

Task is the main class of ClusterShell commands execution support. It represents the whole application task (if application is single-threaded, see note below). Its interface is the main entry point to submit work to do (launch commands, gather outputs, arm timers, copy files, etc.).

Threading note

A ClusterShell's Task is bound to a specific execution thread. The Task class is a ''per-thread Singleton class''.

Usage

Getting a task

For single-threaded applications, a Task is a simple singleton which instance is available through the task_self() function. The task_self() function is available at the module Task root:

from ClusterShell.Task import task_self

task = task_self()

Submitting commands

You can submit a set of commands for local or distant execution (in parallel) with the help of the following methods:

 Task.shell(...) # submit local or distant command for execution
 Task.copy(...)  # copy a file to distant nodes
 Task.rcopy(...) # copy distant file or directory to local node

Local usage:

 task.shell(command [, key=key] [, handler=handler] [, timeout=secs])

Distant usage:

 task.shell(command, nodes=nodeset [, handler=handler] [, timeout=secs])

Starting task

Once the work submitted through the shell(), copy() or rcopy() methods, start the Task execution with the following method:

task.resume()

At this time, all previously submitted commands will start in the associated Task's thread. For a single-threaded application, the current thread will be blocked until the end of the commands execution.

Easy "submit & run"

Additionally, the library provides a convenience method Task.run() to run a command (locally or on a set of nodes):

task.run([command, nodes=nodeset [, handler=handler] [, timeout=secs]])

With arguments, it will schedule a command exactly like a Task.shell() would have done it and run it.

Coding models

Two coding/usage models are available with the ClusterShell library, for each Task:

  • sequential model: each execution waits for the end of all commands, ie. when task.resume() returns,
  • event-based model: the application derives the EventHandler class to listen for events.

Sequential model

The sequential model is convenient for administration scripts that don't need any interaction during commands execution.

The script access to the standard output (automatic gathering) and to return codes through:

Example of command execution on distant nodes:

from ClusterShell.Task import task_self

task = task_self()

task.run("/bin/uname -r", nodes="green[36-39,133]")

for buf, nodes in task.iter_buffers():
    print nodes, buf

Result:

['green37', 'green38', 'green133', 'green36', 'green39'] 2.6.18-164.11.1.el5

Similar example but with multiple commands:

from ClusterShell.Task import task_self

task = task_self()

task.shell("/bin/uname -r", nodes="green[36-39,133]")
task.shell("/bin/uname -p", nodes="green[36-39,133]")

task.resume()

for buf, nodes in task.iter_buffers():
    print nodes, buf

Result:

['green37', 'green38', 'green133', 'green36', 'green39'] 2.6.18-164.11.1.el5
['green37', 'green38', 'green133', 'green36', 'green39'] x86_64

Event-based model

The event-based model is required when the application needs to interact with the user during while commands are executing.

To use it, you need to:

  • derive the EventHandler class and implement choosen ev_* methods (for example: ev_start(), ev_read(), ev_close() ...)
  • instantiate this class and add it as a parameter when calling Task.shell()

Example of Task.shell() call:

task.shell(“/bin/uname -r“, nodes=green[36-39,133]“, handler=MyHandler())

Example of use: filter standard outputs of commands during their execution:

from ClusterShell.Task import task_self
from ClusterShell.Event import EventHandler

class MyHandler(EventHandler):
    def ev_read(self, worker):
        node, buf = worker.last_read()
        if buf.find(".el5") < 0:
            print "%s: %s" % (node, buf)

task = task_self()

task.run("/bin/uname -a", nodes="nova[32-159]", handler=MyHandler())

Result:

 nova142: Linux nova142 2.6.25.11-cea4 #1 SMP Tue Dec 2 15:47:32 CET 2008 x86_64 x86_64 x86_64 GNU/Linux
 ...
Clone this wiki locally