2011-06-16 12 views
9

En mi trabajo con mi profesor tengo que entrar a nuestro servidor y desde allí me paso a cada nodo para ejecutar nuestros programas. Intento escribir un programa de Python que me permita hacer todo lo que necesito hacer en el nodo remoto desde mi máquina local. Los comandos que va a correr en los nodos son:SSH a la máquina a través de un host del medio

  • archivos cp desde la máquina local a nodos remotos
  • ejecutar un programa en cada nodo
  • recuperar archivos de los nodos a mi máquina local
  • tal vez sea posible copiar sobre un programa fortran y compilarlo en los nodos y también verificar los nodos para ver si hay algún programa en ejecución.

Ahora hago mis archivos de entrada en mi máquina local, los reproduzco en el servidor, luego copio los archivos en cada nodo y ejecuto nuestro programa fluid_dynamics en cada nodo. Luego hago lo contrario para devolver nuestra salida a mi máquina local.

Estaba buscando paramiko pero no puedo entender cómo puedo usarlo para llegar desde mi máquina local a los nodos porque debo pasar por el servidor. -ssh locales -> Servidor -> -ssh nodos

¿Hay una manera de hacer esto en Python o debería probar algo distinto, como: usando:

os.system(ssh -t server ssh node 'command') 

o hacer una fiesta scripts en el servidor para cada uno de los diferentes comandos (compile.sh, move_inputs.sh, retrieve_outputs.sh) y luego simplemente conectarse al servidor y ejecutar los scripts bash.

Lo siento si esto no tiene sentido o si está mal redactado, se agradece cualquier ayuda.

Información adicional: La razón por la que estoy usando python es porque quiero que el programa pueda hacer los archivos de entrada, enviarlos a los nodos y recuperar los archivos de salida, y finalmente generar gráficos de nuestros datos. Ya tengo un código para generar nuestros archivos de entrada y para hacer los gráficos de las salidas.

Respuesta

7

No necesita Python para hacer esto. Compruebe el ProxyCommand configuration option for SSH. Aquí hay un tutorial que explica los detalles.

+0

Voy a mirar en esta. La razón por la que estoy usando python es porque quiero que el programa pueda hacer los archivos de entrada, enviarlos a los nodos y recuperar los archivos de salida, y finalmente generar gráficos de nuestros datos. Ya tengo un código para generar nuestros archivos de entrada y para hacer los gráficos de las salidas. – Russss

+0

Aunque no lo he probado, estoy bastante seguro de que la configuración de SSH con ProxyCommand funcionará incluso si tiene SSH de Python. – badzil

5

Con un truco de mi colega, puede ssh/scp de local a nodos directamente.

Editar su archivo ~/.ssh/config:

Host * 
ControlMaster auto 
ControlPath ~/.ssh/master-%[email protected]%h:%p 

Host node1 node2 or node* 
ProxyCommand ssh server 'nc -w 5 %h 22' 

Que se diviertan!

+0

También hago esto, pero hay un par de inconvenientes en el enfoque de ControlMaster. Este es un buen resumen: http://www.anchor.com.au/blog/2010/02/ssh-controlmaster-the-good-the-bad-the-ugly/ – Mzzzzzz

3

Usted puede hacer esto mediante la creación de un túnel a través de su servidor para el nodo:

import os, sys, shlex 
import subprocess 
import paramiko 

cmd = "ssh -f -N -p " + str(serverport) + " -l " + serveruser + " -L " + str(tunnelport) + ":" + nodehost + ":" + str(nodeport) + " " + serverhost 
args = shlex.split(cmd) 
tun = subprocess.Popen(args) 
stat = tun.poll() 

Una vez que el túnel es configurar usted puede ftp a los nodos:

transport = paramiko.Transport(("127.0.0.1", tunnelport)) 
transport.connect(username=nodeusername, password=nodepw) 
sftp = paramiko.SFTPClient.from_transport(transport) 
sftp.put(localfile, remotefile) 

O puede conectar y ejecutar un comando usando paramiko.SSHClient(). connect ("127.0.0.1", puerto = puerto, nombre de usuario = usuario, contraseña = pw) y paramiko.SSHClient(). exec_command (comando).

A continuación, el proceso de túnel se pueden matar por lo tanto:

p = subprocess.Popen(['ps', '-A'], stdout=subprocess.PIPE) 
out, err = p.communicate() 
for line in out.splitlines(): 
    if cmd in line: 
     pid = int(line.split(None, 1)[0]) 
     os.kill(pid, signal.SIGKILL) 
3

Usted puede hacerlo con paramiko:

proxy_command = 'ssh -i %s %[email protected]%s nc %s %s' % (proxy_key, proxy_user, proxy_host, host, 22) 

proxy = paramiko.ProxyCommand(proxy_command) 

client = paramiko.SSHClient() 
client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 
client.connect(host, username=user, password=password, sock=proxy) 

stdin, stdout, stderr = client.exec_command('echo HELLO') 
print "Echo: %s" % (", ".join(stdout.readlines())) 
client.close() 

funciona con SFTPClient también:

proxy_command = 'ssh -i %s %[email protected]%s nc %s %s' % (proxy_key, proxy_user, proxy_host, host, 22) 

proxy = paramiko.ProxyCommand(proxy_command) 

transport = paramiko.Transport(proxy) 
transport.connect(username=user, password=password) 

sftp = paramiko.SFTPClient.from_transport(transport) 
Cuestiones relacionadas