How To Make Fabric Ignore Offline Hosts In The Env.hosts List?
Solution 1:
As of version 1.4 Fabric has a --skip-bad-hosts option that can be set from the command line, or by setting the variable in your fab file.
env.skip_bad_hosts = TrueDocumentation for the option is here: http://docs.fabfile.org/en/latest/usage/fab.html#cmdoption--skip-bad-hosts
Don't forget to explicitly set the timeout value also.
Solution 2:
According to the Fabric documentation on warn_only,
env.warn_only"specifies whether or not to warn, instead of abort, whenrun/sudo/localencounter error conditions.
This will not help in the case of a server being down, since the failure occurs during the SSH attempt before executing run/sudo/local.
One solution would be to create a function to check if each server is up prior to executing your tasks. Below is the code that I used.
from __future__ import print_function
from fabric.api import run, sudo, local, env
import paramiko
import socket
host1 = '192.168.200.181'
offline_host2 = '192.168.200.199'
host3 = '192.168.200.183'
env.hosts = [host1, offline_host2, host3]
defdf_h():
    if _is_host_up(env.host, int(env.port)) isTrue:
        run("df -h | grep sda1")
def_is_host_up(host, port):
    # Set the timeout
    original_timeout = socket.getdefaulttimeout()
    new_timeout = 3
    socket.setdefaulttimeout(new_timeout)
    host_status = Falsetry:
        transport = paramiko.Transport((host, port))
        host_status = Trueexcept:
        print('***Warning*** Host {host} on port {port} is down.'.format(
            host=host, port=port)
        )
    socket.setdefaulttimeout(original_timeout)
    return host_status
Solution 3:
You're not using it improperly. You can even just provide --warn-only=true on the command line. It's the documented method suggested by the development team.
Solution 4:
Based on Matthew's answer, I came up with a decorator that accomplishes just that:
from __future__ import with_statement
from paramiko import Transport
from socket import getdefaulttimeout, setdefaulttimeout
from fabric.api import run, cd, env, roles
roledefs = {
    'greece': [
        'alpha',
        'beta'
    ],
    'arabia': [
        'kha',
        'saad'
    ]
}
env.roledefs = roledefs
defif_host_offline_ignore(fn):
    defwrapped():
        original_timeout = getdefaulttimeout()
        setdefaulttimeout(3)
        try:
            Transport((env.host, int(env.port)))
            return fn()
        except:
            print"The following host appears to be offline: " + env.host
        setdefaulttimeout(original_timeout)
    return wrapped
@roles('greece')@if_host_offline_ignoredefhello_greece():
    with cd("/tmp"):
        run("touch hello_greece")
@roles('arabia')@if_host_offline_ignoredefhello_arabia():
    with cd("/tmp"):
        run("touch hello_arabia")
It is especially useful when you have multiple hosts and roles.
Post a Comment for "How To Make Fabric Ignore Offline Hosts In The Env.hosts List?"