JahMyst
JahMyst

Reputation: 1686

Fabric - Test SSH connection to multiple hosts

I have a Python script that uses fabric library to test SSH connection to multiple hosts. I want to gather all the results in one list:

...
import fabric
from fabric.api import *

results = []

@parallel
def test_connection():
  global results
  try:
    run('ls')
    results += "%s: SUCCESS" % env.host
  except Exception as e:
    results += "%s: FAILURE. Exception: %e" % (env.host, e)

if __name__ == '__main__':
    tasks.execute(test_connection)
    print results

When I execute the script, I get the following:

Traceback (most recent call last):
  File "./test_ssh.py", line 99, in <module>
    tasks.execute(test_connection)
  File "/Library/Python/2.7/site-packages/fabric/tasks.py", line 387, in execute
    multiprocessing
  File "/Library/Python/2.7/site-packages/fabric/tasks.py", line 277, in _execute
    return task.run(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/fabric/tasks.py", line 174, in run
    return self.wrapped(*args, **kwargs)
  File "./test_ssh.py", line 96, in test_connection
    results += "%s: FAILURE. Exception: %e" % (env.host, e)
UnboundLocalError: local variable 'results' referenced before assignment

I think it is because test_connection runs it's own context so it doesn't have access to results.

Is there another way I can gather my results then ?

Upvotes: 2

Views: 3063

Answers (1)

2ps
2ps

Reputation: 15916

The trick is that you can actually return results from parallel execution:

@parallel
def test_connection():
  try:
    run('ls')
    return True
  except Exception:
    return False

Now when you call your task, you will get:

result = execute(test_connection)
results = [ ('HOST %s succeeded' % key) if value else ('HOST %s failed' % key) for key, value in result.items() ]

Upvotes: 4

Related Questions