Multiple file support with scp

  • Post author:
  • Post category:Python

Paramiko doesn't provide a scp implementation, so I've been using my own for a while. http://blogs.sun.com/janp/entry/how_the_scp_protocol_works (link now unfortunately dead) provides good documentation about the scp protocol, but it missed out on one detail I needed -- how to send more than one file in a given session. In the end I implemented a simple scp logger to see what the protocol was doing during the copying of files. My logger said this: >>> New command invocation: /usr/bin/scp -d -t /tmp O: \0 I: C0644 21 a\n O: \0 I: file a file a file a\n\0 O: \0 I: C0644 21 b\n O: \0 I: file b file b file b\n\0 O: \0 >>>stdin closed >>> stdout closed >>> stderr closed It turns out its important to wait for those zeros by the way. So, here's my implementation of the protocol to send more than one file. Turning this into paramiko code is left as an exercise for the reader. #!/usr/bin/python import fcntl import os import select import string import subprocess import sys import traceback def printable(s): out = '' for c in s: if c == '\n': out += '\\n' elif c in string.printable: out += c else: out…

Continue ReadingMultiple file support with scp

Calculating a SSH host key with paramiko

  • Post author:
  • Post category:Python

I needed to compare a host key from something other than a known_hosts file with what paramiko reports as part of the SSH connection today. If you must know, the host keys for these machines are retrieved a XMLRPC API... It turned out to be a lot easier than I thought. Here's how I produced the host key entry as it appears in that API (as well as in the known_hosts file): #!/usr/bin/python # A host key calculation example for Paramiko. # Args: # 1: hostname import base64 import os import paramiko import socket import sys # Socket connection to remote host sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((sys.argv[1], 22)) # Build a SSH transport t = paramiko.Transport(sock) t.start_client() key = t.get_remote_server_key() print '%s %s' %(key.get_name(), base64.encodestring(key.__str__()).replace('\n', '')) t.close() sock.close() Note that I could also have constructed a paramiko key object based on the output of the XMLRPC API and then compared those two objects, but I prefer the human readable strings.

Continue ReadingCalculating a SSH host key with paramiko

paramiko exec_command timeout

  • Post author:
  • Post category:Python

I have a paramiko program which sshs to a large number of machines, and sometimes it hits a machine where Channel.exec_command() doesn't return. I know this is a problem with the remote machine, because the same thing happens when I try to ssh to the machine from the command line. However, I don't have any way of determining which machines are broken beforehand. Paramiko doesn't support a timeout for exec_command(), so I am looking for a generic way of running a function call with a timeout. I can see sample code which does this using threads, but that's pretty ugly. I can't use SIGALARM because I am not running on the main thread. Can anyone think of a better way of doing this?

Continue Readingparamiko exec_command timeout

Weird paramiko problem

  • Post author:
  • Post category:Python

I had a strange paramiko problem the other day. Sometimes executing a command through a channel (via the exec_command() call) would result in an exit code being returned, but no stdout or stderr. This was for a command I was absolutely sure always returns output, and it wasn't consistent -- I'd run batches of commands and about 10% of them would fail, but not always on the same machine and not always at the same time. I spent ages looking at my code, and the code for the command running at the other end of the channel. Then it occurred to me that this seemed a lot like a race condition. I started looking at the code for the paramiko Channel class, and ended up deciding that the answer was to check that the eof_received member variable was true before trying to close the channel. It turns out this just works. I've my code running commands for a couple of days now and have had zero more instances of the "no output, but did exit" error. So, there you go. Its a shame that member variable doesn't have accessors and isn't documented though. I guess that makes my code a…

Continue ReadingWeird paramiko problem

Executing a command with paramiko

  • Post author:
  • Post category:Python

I wanted to provide a simple example of how to execute a command with paramiko as well. This is quite similar to the scp example, but is nicer than executing a command in a shell because there isn't any requirement to do parsing to determine when the command has finished executing. #!/usr/bin/python # A simple command example for Paramiko. # Args: # 1: hostname # 2: username # 3: command to run import getpass import os import paramiko import socket import sys # Socket connection to remote host sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((sys.argv[1], 22)) # Build a SSH transport t = paramiko.Transport(sock) t.start_client() t.auth_password(sys.argv[2], getpass.getpass('Password: ')) # Start a cmd channel cmd_channel = t.open_session() cmd_channel.exec_command(sys.argv[3]) data = cmd_channel.recv(1024) while data: sys.stdout.write(data) data = cmd_channel.recv(1024) # Cleanup cmd_channel.close() t.close() sock.close()

Continue ReadingExecuting a command with paramiko

Implementing SCP with paramiko

  • Post author:
  • Post category:Python

Regular readers will note that I've been interested in how scp works and paramiko for the last couple of days. There are previous examples of how to do scp with paramiko out there, but the code isn't all on one page, you have to read through the mail thread and work it out from there. I figured I might save someone some time (possibly me!) and note a complete example of scp with paramiko... #!/usr/bin/python # A simple scp example for Paramiko. # Args: # 1: hostname # 2: username # 3: local filename # 4: remote filename import getpass import os import paramiko import socket import sys # Socket connection to remote host sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((sys.argv[1], 22)) # Build a SSH transport t = paramiko.Transport(sock) t.start_client() t.auth_password(sys.argv[2], getpass.getpass('Password: ')) # Start a scp channel scp_channel = t.open_session() f = file(sys.argv[3], 'rb') scp_channel.exec_command('scp -v -t %s\n' % '/'.join(sys.argv[4].split('/')[:-1])) scp_channel.send('C%s %d %s\n' %(oct(os.stat(sys.argv[3]).st_mode)[-4:], os.stat(sys.argv[3])[6], sys.argv[4].split('/')[-1])) scp_channel.sendall(f.read()) # Cleanup f.close() scp_channel.close() t.close() sock.close()

Continue ReadingImplementing SCP with paramiko

End of content

No more pages to load