2009-08-19 11 views
5

Sono appena diventato l'amministratore di sistema per il cluster del mio gruppo di ricerca e, in tal senso, sono un principiante. Sto cercando di creare alcuni strumenti per monitorare la rete e ho bisogno di aiuto per iniziare a implementarli con python (la mia lingua madre).Interfaccia con computer remoti usando Python

Ad esempio, vorrei vedere chi è connesso a macchine remote. A mano, vorrei ssh e who, ma come potrei ottenere queste informazioni in uno script per la manipolazione? Qualcosa di simile,

import remote_info as ri 
ri.open("foo05.bar.edu") 
ri.who() 

Out[1]: 
hutchinson tty7   2009-08-19 13:32 (:0) 
hutchinson pts/1  2009-08-19 13:33 (:0.0) 

Allo stesso modo per le cose come cat /proc/cpuinfo per ottenere le informazioni di processore di un nodo. Un punto di partenza sarebbe davvero grandioso. Grazie.

risposta

2

Ecco una soluzione semplice, a basso costo per iniziare

from subprocess import * 
p = Popen('ssh servername who', shell=True, stdout=PIPE) 
p.wait() 
print p.stdout.readlines() 

rendimenti (ad esempio)

['usr  pts/0  2009-08-19 16:03 (kakapo)\n', 
'usr  pts/1  2009-08-17 15:51 (kakapo)\n', 
'usr  pts/5  2009-08-17 17:00 (kakapo)\n'] 

e per cpuinfo:

p = Popen('ssh servername cat /proc/cpuinfo', shell=True, stdout=PIPE) 
+0

Bello. Questo è stato il primo codice che ho avuto modo di lavorare. Domanda: Sai quando termina la connessione ssh? – physicsmichael

+0

subito dopo aver eseguito il comando. – Peter

+0

@Peter: se ho bisogno di un'interazione con un host remoto (risposta su prompt, ecc.) Dovrei usare Pexpect o c'è una libreria incorporata con tale funzionalità – legesh

2

ho usato Pexpect, che ti consente di accedere alle macchine, inviare comandi, leggere l'output e reagire con successo. Ho anche iniziato un progetto open source intorno a questo, Proxpect - che non sono stati aggiornati da secoli, ma sto divagando ...

0

Questo copre le basi. Si noti l'uso di sudo per le cose che necessitavano di maggiori privilegi. Abbiamo configurato sudo per consentire quei comandi per quell'utente senza aver bisogno di una password digitata.

Inoltre, tenere presente che è necessario eseguire ssh-agent per rendere questo "ragionevole". Ma tutto sommato, funziona davvero bene. L'esecuzione di deploy-control httpd configtest controllerà la configurazione di apache su tutti i server remoti.

#!/usr/local/bin/python 

import subprocess 
import sys 

# The [email protected]: for the SourceURLs (NO TRAILING SLASH) 
RemoteUsers = [ 
     "[email protected]", 
     "[email protected]", 
     ] 

################################################################################################### 
# Global Variables 
Arg        = None 


# Implicitly verified below in if/else 
Command = tuple(sys.argv[1:]) 

ResultList = [] 
################################################################################################### 
for UH in RemoteUsers: 
     print "-"*80 
     print "Running %s command on: %s" % (Command, UH) 

     #---------------------------------------------------------------------------------------------- 
     if Command == ('httpd', 'configtest'): 
       CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd configtest')) 

     #---------------------------------------------------------------------------------------------- 
     elif Command == ('httpd', 'graceful'): 
       CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd graceful')) 

     #---------------------------------------------------------------------------------------------- 
     elif Command == ('httpd', 'status'): 
       CommandResult = subprocess.call(('ssh', UH, 'sudo /sbin/service httpd status')) 

     #---------------------------------------------------------------------------------------------- 
     elif Command == ('disk', 'usage'): 
       CommandResult = subprocess.call(('ssh', UH, 'df -h')) 

     #---------------------------------------------------------------------------------------------- 
     elif Command == ('uptime',): 
       CommandResult = subprocess.call(('ssh', UH, 'uptime')) 

     #---------------------------------------------------------------------------------------------- 
     else: 
       print 
       print "#"*80 
       print 
       print "Error: invalid command" 
       print 
       HelpAndExit() 

     #---------------------------------------------------------------------------------------------- 
     ResultList.append(CommandResult) 
     print 


################################################################################################### 
if any(ResultList): 
     print "#"*80 
     print "#"*80 
     print "#"*80 
     print 
     print "ERRORS FOUND. SEE ABOVE" 
     print 
     sys.exit(0) 

else: 
     print "-"*80 
     print 
     print "Looks OK!" 
     print 
     sys.exit(1) 
1

Il modulo pexpect consente di interfacciare ssh. Più o meno, ecco come sarà il tuo esempio.

child = pexpect.spawn('ssh servername') 
child.expect('Password:') 
child.sendline('ABCDEF') 
(output,status) = child.sendline('who') 
+0

Ad esempio, va bene, ma si noti che l'autenticazione come questa è generalmente considerata una cattiva idea. L'autenticazione SSH basata su chiave pubblica è più sicura ... E almeno non devi assicurarti che il tuo script non sia leggibile da tutto il mondo dopo ogni modifica accidentale. – drdaeman

+0

L'output di 'child.sendline ('who')' sembra essere il numero 4 ... Cosa mi manca? – physicsmichael

+0

Ho avuto lo stesso con pexpect, che cosa dà con esso? – Jon

0

Il tessuto è un modo semplice per automatizzare alcune attività semplici come questo, la versione Attualmente sto usando permette di avvolgere i comandi in questo modo:

run('whoami', fail='ignore') 

è possibile specificare le opzioni di configurazione (config .fab_user, config.fab_password) per ogni macchina di cui hai bisogno (se vuoi automatizzare la gestione della password del nome utente).

Più informazioni su Tessuto qui:

http://www.nongnu.org/fab/

C'è una nuova versione che è più Pythonic - non sono sicuro se questo sta per essere meglio per voi INT suo caso ... Lavori per me al momento attuale ...

1

Se le tue esigenze sono troppo grandi per "ssh remote-host.example.org who", allora c'è una fantastica libreria Python, chiamata RPyC. Ha la cosiddetta modalità "classica" che consente di eseguire quasi in modo trasparente il codice Python sulla rete con diverse linee di codice. Strumento molto utile per ambienti fidati.

Ecco un esempio da Wikipedia:

import rpyc 
# assuming a classic server is running on 'hostname' 
conn = rpyc.classic.connect("hostname") 

# runs os.listdir() and os.stat() remotely, printing results locally 
def remote_ls(path): 
    ros = conn.modules.os 
    for filename in ros.listdir(path): 
     stats = ros.stat(ros.path.join(path, filename)) 
     print "%d\t%d\t%s" % (stats.st_size, stats.st_uid, filename) 

remote_ls("/usr/bin") 

Se siete interessati, c'è a good tutorial on their wiki.

Ma, naturalmente, se si sta perfettamente bene con le chiamate ssh usando Popen o semplicemente non si vuole eseguire daemon separato "RPyC", allora questo è sicuramente un eccesso.