2013-01-09 17 views
11

Ho bisogno di un programma Python che sto usando per interrogare un server remoto per la connettività SSH e notificarlo quando è disponibile. Attualmente sto facendo questo usando paramiko; tentare di connettersi, in caso di errore, attendere e riprovare fino al successo o al massimo tentativi. Funziona, ma è un po 'goffo. Anche paramiko sembra o connettere o lanciare un errore, quindi l'unico modo che ho potuto vedere per farlo era con un try/except block che è cattivo, cattivo, cattivo. Ecco il metodo:Modo elegante per testare la disponibilità SSH

def check_ssh(self, ip, user, key_file, initial_wait=0, interval=0, retries=1): 
    ssh = paramiko.SSHClient() 
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 

    sleep(initial_wait) 

    for x in range(retries): 
     try: 
      ssh.connect(ip, username=user, key_filename=key_file) 
      return True 
     except Exception, e: 
      print e 
      sleep(interval) 
    return False 

Ci deve essere una soluzione più elegante di questa. Paramiko è la mia libreria SSH preferita, ma sono aperta a qualsiasi suggerimento qui.

Per chiarire, vorrei evitare di usare try/se non come un mezzo per controllare il normale flusso di esecuzione di codice - dovrebbe essere usato per la cattura di errori effettivi come cattivo chiave host, utente non valido ecc

+7

"l'unico modo che potevo vedere per fare questo era con un tentativo/eccetto il blocco che è cattivo, cattivo, cattivo" perché è cattivo? –

+9

Hai sicuramente ragione nel rilevare che l'eccezione è errata. Cogliere l'eccezione specifica lanciata da paramiko, tuttavia, non è affatto male. –

+0

In effetti, ma l'utilizzo della gestione delle eccezioni come metodo di flusso del programma è generalmente errato, come da: http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Exceptions – nightowl

risposta

12

Come menzionato nel commento di frb, un blocco try ... except rappresenta un buon approccio per verificare la disponibilità di un servizio specifico. Non si dovrebbe tuttavia utilizzare un blocco "catch-all" except, ma limitarlo alle eccezioni specifiche che si verificano se il servizio non è disponibile.

Secondo la documentazione, paramiko.SSHClient.connect può generare eccezioni diverse, a seconda del problema che si è verificato durante la connessione. Se si desidera catturare tutti coloro, il tuo blocco try ... except sarebbe simile a questa:

try: 
    ssh.connect(ip, username=user, key_filename=key_file) 
    return True 
except (BadHostKeyException, AuthenticationException, 
     SSHException, socket.error) as e: 
    print e 
    sleep(interval) 

Se solo un sottoinsieme di queste eccezioni è rilevante per il vostro caso, mettere solo quelli nella tupla dopo except.

+0

Punto giusto sul mio codice lassista che specifica solo un'eccezione generica: p Ho bisogno di un try/catch suppongo per cose come una cattiva chiave dell'host in quanto questi sono errori reali non "il server non è ancora attivo" - il punto è che non voglio che il blocco try/except controlli il ciclo di attesa (cioè il flusso normale del codice). – nightowl

Problemi correlati