2009-12-24 3 views
11

Dies ist mit meiner previous question verwandt, aber eine andere.Wie mache Fabric Offline-Hosts in der Liste env.hosts ignorieren?

Ich habe folgendes fabfile:

from fabric.api import * 

host1 = '192.168.200.181' 
offline_host2 = '192.168.200.199' 
host3 = '192.168.200.183' 

env.hosts = [host1, offline_host2, host3] 
env.warn_only = True 

def df_h(): 
    with settings(warn_only=True): 
     run("df -h | grep sda3") 

Und der Ausgang ist:

[192.168.200.199] run: df -h | grep sda3 

Fatal error: Low level socket error connecting to host 192.168.200.199: No route to host 

Aborting. 

Nach der Ausführung des Offline-Server trifft, es bricht sofort, unabhängig von den anderen Servern in der env. Gastgeber Liste.

Ich habe die Umgebungseinstellung "warn_only = True" verwendet, aber vielleicht verwende ich sie nicht richtig.

Wie kann ich dieses Verhalten so ändern, dass es nur den Fehler druckt und weiter ausführt?

Antwort

15

Nach dem Fabric documentation on warn_only,

env.warn_only „gibt an, ob oder nicht zu warnen, statt Abbruch, wenn run/sudo/local Begegnung Fehlerbedingungen.

Dies wird nicht in Hilfe der Fall, dass ein Server ausgefallen ist, da der Fehler während des SSH-Versuchs vor der Ausführung auftritt run/sudo/local.

Eine Lösung wäre, eine Funktion zu erstellen, um zu überprüfen, ob jeder Server aktiv ist, bevor Sie Ihre Aufgaben ausführen. Unten ist der Code, den ich verwendet habe.

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] 

def df_h(): 
    if _is_host_up(env.host, int(env.port)) is True: 
     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 = False 
    try: 
     transport = paramiko.Transport((host, port)) 
     host_status = True 
    except: 
     print('***Warning*** Host {host} on port {port} is down.'.format(
      host=host, port=port) 
     ) 
    socket.setdefaulttimeout(original_timeout) 
    return host_status 
+1

Ich habe einen ähnlichen Weg, um dies zu tun, aber viel naiv - ich wickelte Ping-Befehl mit Subprozess-Modul -_- " Ich sollte auf jeden Fall mehr in die Module, die Sie verwendet haben. Vielen Dank, Mann. –

+0

@ jevonearth's Antwort schlägt die Methode fabric> = v1.4 vor, indem Sie das Flag --skip-bad-hosts oder env.skip_bad_hosts = True in der Funktion verwenden – sreenivas

1

Sie verwenden es nicht falsch. Sie können auch einfach --warn-only=true in der Befehlszeile angeben. It's the documented method suggested by the development team.

+1

Der Parameter sollte "--warn-only" sein. "Fab --warn-only df_h" gibt jedoch dieselbe Fehlermeldung aus. Es scheint, dass ein Verbindungsfehler nicht durch die Einstellung "warn_only" abgedeckt wird. –

1

Basierend auf Matthew Antwort kam ich mit einem Dekorateur auf, die genau das erreicht:

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 


def if_host_offline_ignore(fn): 
    def wrapped(): 
     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_ignore 
def hello_greece(): 
    with cd("/tmp"): 
     run("touch hello_greece") 


@roles('arabia') 
@if_host_offline_ignore 
def hello_arabia(): 
    with cd("/tmp"): 
     run("touch hello_arabia") 

Es ist besonders nützlich, wenn Sie mehrere Hosts und Rollen haben.

19

Ab Version 1.4 Fabric verfügt über eine --skip-bad-hosts Option, die über die Befehlszeile oder durch Festlegen der Variablen in Ihrer Fab-Datei festgelegt werden kann.

env.skip_bad_hosts = True 

Dokumentation für die Option ist hier: http://docs.fabfile.org/en/latest/usage/fab.html#cmdoption--skip-bad-hosts

Vergessen Sie nicht explizit festgelegt, um den Timeout-Wert auch.

+1

Diese Antwort ist die richtige für Fabric> = v1.4 und muss es sein upvoted –

Verwandte Themen