Content here is by:
Michael Still
mikal@stillhq.com

All my Open Source projects
Extracted view of CVS
Home
Site map

See recent comments. RSS feed of all comments.

ImageMagick book

MythTV book








Sun, 05 Oct 2008



paramiko exec_command timeout

    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?

    Tags for this post: python(S) paramiko(S)

posted at: 12:20 | path: /python/paramiko | permanent link to this entry


Tue, 16 Sep 2008



Weird paramiko problem

    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 little more fragile than I would be happy with.

    Tags for this post: python(S) paramiko(S)

posted at: 11:41 | path: /python/paramiko | permanent link to this entry


Wed, 03 Sep 2008



Executing a command with paramiko

    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()
      


    Tags for this post: python(S) paramiko(S)

posted at: 15:11 | path: /python/paramiko | permanent link to this entry


Implementing SCP with paramiko

    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()
      


    Tags for this post: python(S) paramiko(S)

posted at: 13:28 | path: /python/paramiko | permanent link to this entry