5

I am trying to copy a file between two servers from a localServer, say from server-A to server-B. I am using paramiko package in python.

So there are three servers namely, localServer, server-A and server-B. Please see the below code, this is self explanatory and please let me know where I am going wrong.

Algorithm I am using:

  1. I am trying to run paramiko_test.py file from localServer.
  2. paramiko_test.py executes copy.py file in server-A.
  3. copy.py copies file source.txt file in server-A to server-B using SFTP.

When I run copy.py from server-A, it is working correct. But when I run paramiko_test.py from localServer (which indirectly executes copy.py in server-A), it is not working!

From logs, I got to know that there is a successful connection from server-A to server-B, but after that the SFTP part is not working!

Question: Can we invoke a SFTP client within a SFTP client? Is there any better way to copy files between two servers?

Please help me where I am going wrong.

server-A, file:copy.py:

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('<server-B-IP>', username='serverB', password='passwd')

print "connected successfully!"

sftp = ssh.open_sftp()
print sftp
sftp.put('source.txt','/home/serverB/destination.txt' )
sftp.close()
print "copied successfully!"

ssh1.close()
exit()

localServer, paramiko_test.py:

import paramiko

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('<server-A-IP>', username='serverA', password='passwd')

print "connected successfully!"

stdin, stdout, stderr = ssh.exec_command("python /home/username/copy.py")

print stdout.readlines()

print "copied successfully!"

ssh.close()
exit()

The output of stderr.readlines() is:

Traceback (most recent call last):
 File "/home/sitaram/sumanth/test_progs/copy.py", line 12, in <module>
 sftp1.put('./sumanth_temp.txt','/home/ncloudadmin/sumanth.txt' ) 
 File "/usr/lib/pymodules/python2.6/paramiko/sftp_client.py", line 558, in put
 file_size = os.stat(localpath).st_size
OSError: [Errno 2] No such file or directory: './sumanth_temp.txt'
Alex L
  • 8,748
  • 5
  • 49
  • 75
Sumanth Lingappa
  • 464
  • 1
  • 6
  • 15
  • 1
    Have you looked at Fabric? It's a bit easier than Paramiko to [work with files](http://docs.fabfile.org/en/1.5/api/contrib/files.html) and can do things like [put a file on a remote server](http://docs.fabfile.org/en/1.5/api/core/operations.html#fabric.operations.put) – Alex L Jan 31 '13 at 12:13
  • Hi Alex, Thanks for your reply. I looked at Fabric, I didnt see anywhere Fabric supporting file transfer between two remote hosts, running script in another local Server. Or is it supported by Fabric?? Please help. – Sumanth Lingappa Feb 01 '13 at 06:12
  • Can you SSH into one of the remote servers, and then SFTP/SCP across? Are you getting anything in your `sterr`? – Alex L Feb 01 '13 at 06:38
  • The output of - `print stderr.readlines()` is `['Traceback (most recent call last):\n', ` `' File "/home/username/copy.py", line 12, in \n', ` `" sftp1.put('./source.txt','/home/serverB/dest_file.txt' ) \n", ` `' File "/usr/lib/pymodules/python2.6/paramiko/sftp_client.py", line 558, in put\n', ` `' file_size = os.stat(localpath).st_size\n', ` `"OSError: [Errno 2] No such file or directory: './source.txt'\n"]` – Sumanth Lingappa Feb 01 '13 at 07:10
  • But I see source.txt is present in the right directory!! – Sumanth Lingappa Feb 01 '13 at 07:11
  • I am not finding any problem if I run the same copy.py file from serverA !! – Sumanth Lingappa Feb 01 '13 at 07:11
  • I've added your output to your question. In `copy.py` could you print `os.getcwd()`? You might be running in the wrong directory, so Python can't find your file. You could also try using a full filepath - i.e. `'\user\sumanth\sumanth_temp.txt'` – Alex L Feb 01 '13 at 07:11
  • hey Alex, thanks for the help :) It worked. I gave absolute path . But I still wonder why it was not working before!!! – Sumanth Lingappa Feb 01 '13 at 07:20
  • Fabric is your best bet, run rsync command on any of the host servers using api.run() – Dami Feb 01 '13 at 08:11

1 Answers1

9

Question is year old, so probably not relevant anymore, but maybe it will be useful to others. The problem is in your copy.py.

sftp.put('source.txt','/home/serverB/destination.txt' )

where is source.txt located? Either provide full path, or if the file is always located in in the same dir as copy.py you could modify your paramiko_test.py

ssh.exec_command("cd /home/username/; python /home/username/copy.py")
Tadzys
  • 1,044
  • 3
  • 16
  • 22
  • will the `sftp.put` or `sftp.get` make sure that the `ssh.exec_command` will not execute until they are done with transferring the file? – weefwefwqg3 Nov 01 '17 at 21:23