最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

python - Skip bad hosts and return good results on Fabric call - Stack Overflow

programmeradmin5浏览0评论

I would like to send a remote command to multiple hosts using the Python Fabric library. The following code works as long as all hosts are available

#!/usr/bin/python3
import fabric

group = fabric.ThreadingGroup('boss1', 'boss2')
results = group.run('uname -a', hide=True, timeout=5)

for _connection, _result in results.items():
    print(f'{_connection.host}: {_result.stdout.strip()}')

If one of the hosts is unavailable I get a timeout error such as the following

fabric.exceptions.GroupException: {<Connection host=boss1 user=ec2-user>: TimeoutError(60, 'Operation timed out'), <Connection host=boss2 user=ec2-user>: <Result cmd='uname -a' exited=0>}

I would (1) like to reduce the timeout to 5 seconds (as is specified in group.run()) and (2) isolate the error to only the bad host and return information from the successful one(s).

I have found documentation about connection_timeout, but only group.run() seems to accept a timeout keyword and it does not reduce from 60 seconds.

I have also found documentation about a skip_bad_hosts keyword but cannot insert it into my code without a runtime error.

What is the best way to skip over an error on one system and return results from the others?

Python 3, Fabric 3

I would like to send a remote command to multiple hosts using the Python Fabric library. The following code works as long as all hosts are available

#!/usr/bin/python3
import fabric

group = fabric.ThreadingGroup('boss1', 'boss2')
results = group.run('uname -a', hide=True, timeout=5)

for _connection, _result in results.items():
    print(f'{_connection.host}: {_result.stdout.strip()}')

If one of the hosts is unavailable I get a timeout error such as the following

fabric.exceptions.GroupException: {<Connection host=boss1 user=ec2-user>: TimeoutError(60, 'Operation timed out'), <Connection host=boss2 user=ec2-user>: <Result cmd='uname -a' exited=0>}

I would (1) like to reduce the timeout to 5 seconds (as is specified in group.run()) and (2) isolate the error to only the bad host and return information from the successful one(s).

I have found documentation about connection_timeout, but only group.run() seems to accept a timeout keyword and it does not reduce from 60 seconds.

I have also found documentation about a skip_bad_hosts keyword but cannot insert it into my code without a runtime error.

What is the best way to skip over an error on one system and return results from the others?

Python 3, Fabric 3

Share Improve this question asked yesterday shepstershepster 5091 gold badge5 silver badges17 bronze badges 1
  • Have you looked at the source? fabric is a thin wrapper around paramiko and invoke, so it doesn't handle the timeouts on its own. Youprobably need to create a fabric.Connection and specify the connection_timeout. – Tim Roberts Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 0

The timeout needs to be specified in .ThreadingGroup() (with a different parameter name) and if you capture the exception you can reveal which commands were successful or not.

#!/usr/bin/python3
import fabric

group = fabric.ThreadingGroup('boss1', 'boss2', connect_timeout=5)

try:
    results = group.run('uname -nsr', hide=True)
except fabric.exceptions.GroupException as err:
    results = err.result


for _connection, _result in results.items():
    if hasattr(_result, 'stdout'):
        print(f'{_connection.host}: {_result.stdout.strip()}')
    else:
        print(f'{_connection.host}: {_result}')

Sample output:

boss1: timed out
boss2: Linux boss2 4.14.355-275.582.amzn2.x86_64
发布评论

评论列表(0)

  1. 暂无评论