Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I collect fabric task output and print a summary for multiple hosts?

Tags:

python

fabric

In fabric, I have a task collecting something on a per host basis (small example).

from fabric.api import task, run, hide
env.hosts['h1', 'h2', 'h3']

@task
def info():
    with hide('everything'):
        info = run("who | tail -n 1")
        print("On host {0} last user was {1}".format(env.host_string, info))

Run with

fab info

will give something like

[h1] Executing task 'info'
On host h1 last user was userXX  pts/29       2015-07-29 15:57 (:0)
[h2] Executing task 'info'
On host h2 last user was userXX  pts/29       2015-07-29 16:57 (:0)
[h3] Executing task 'info'
On host h3 last user was userXX  pts/29       2015-07-29 17:57 (:0)

While this is fine for 3 or 5 hosts, it gets very hard to view for 20 or more hosts (or more complicated output). What I want to do is to accumulate all output for each host and use this to create a summary/overview in the end, after the task was executed on each host.

How would I do that?

like image 351
chris-sc Avatar asked Jul 29 '15 14:07

chris-sc


1 Answers

... while writing this question and after at least an hour of googleing different phrases, I finally found this:

http://docs.fabfile.org/en/1.14/usage/execution.html#leveraging-execute-to-access-multi-host-results

Even though I scanned through this site a couple of times I missed the relevant part, and therefore thought to post it here with the hope its easier to find if one does not search for the exact phrase on google:

from fabric.api import task, execute, run, runs_once

@task
def workhorse():
    return run("get my infos")

@task
@runs_once
def go():
    results = execute(workhorse)
    print results

So the example from the question can be solved with:

from fabric.api import task, run, hide, execute, runs_once
env.hosts['h1', 'h2', 'h3']

@task
def collect_info():
    with hide('everything'):
        info = run("who | tail -n 1")
        return info

@task
@runs_once
def info():
    collected_output = execute(collect_info)
    for host, info in collected_output.iteritems():
        print("On host {0} last user was {1}".format(host, info))
like image 168
chris-sc Avatar answered Nov 07 '22 15:11

chris-sc