pythonfabricpython-fabric-2

Fabric 2.5, how to skip a host if it is unavailable?


I use Fabric 2.5 and have not many servers (10-20), at any time, everyone can become inaccessible, this is normal behavior. How I can check the connection or skip a bad host?

In Fabric 1.4 we can use --skip-bad-hosts (and env.skip_bad_hosts) to bypass problematic hosts, but this functional now not porting in Fabric 2.5.

I haven’t done anything on this wonderful framework before, maybe I'm doing something wrong? My fabfile.py:

import os

from fabric.connection import Connection
from fabric.tasks import task
from fabric.config import Config

USERNAME = os.getenv('USERNAME')
PASSWORD = os.getenv('PASSWORD')

def get_instance_ips():
    return ['10.10.10.10', '10.10.10.11', '10.10.10.12', '10.10.10.12', ... ]

def get_hosts():
    ips = sorted(get_instance_ips())
    return [{
        "host": f"{USERNAME}@{ip}",
        "connect_kwargs": {"password": PASSWORD},
    } for ip in ips]

@task
def firstTask(c):
    print("CONNECTION....")
    for index, host in enumerate(get_hosts()):
      print(f"****** Run in host {index} at {host['host']} ******")
      remote = Connection(**host)
      remote.run('some action')

Now if any of the addresses is unavailable, I get an error:

...
File "/usr/local/lib/python3.8/site-packages/paramiko/client.py", line 349, in <lambda>
  retry_on_signal(lambda: sock.connect(addr))
  socket.timeout: timed out

I can return to version Fabric 1.4, but I would like to use Fabric 2.5, thanks for any help.


Solution

  • I don't know if this is the best solution, but we can use a try/except for the connection

    hosts = ["admin@web1", "admin@web2"]
    for host in hosts:
        try:
            conn = Connection(host)
            some_function(conn)
        except Exception as e:
            print("ERROR: ", e)