Forum Archive

paramiko crashing on client.connect()

Westacular129

I'm really impressed paramiko was added in the 1.3 update. That's awesome.

However, I'm having some trouble getting it working.

Specifically: calling the 'connect()' method on a SSHClient object is crashing Pythonista.

Sample code:

import paramiko
client = paramiko.SSHClient()
print 'Client instance created'
client.load_host_keys("known_hosts")
print 'Host keys loaded'
client.connect(hostname="mylocalhost", username="myname", password="mypassword")
print 'Connection opened'

Running this outputs the first two print statements then Pythonista crashes. I've tried with and without using a private key instead of a password, and with a couple different hosts. The hosts I'm trying to connect to are listed in the known_hosts file.

Anyone have any insights? Is paramiko working for other people?

(For the record, this is on both an iPad 3 and iPhone 4, both running iOS 6.1.2)

omz

I admit that the paramiko integration is somewhat experimental, and I'm not exactly sure what's causing these crashes, but here's a minimal example that should work:

import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect(hostname="HOSTNAME", username="USER", password="PASSWORD")
stdin, stdout, stderr = client.exec_command('uptime')
print stdout.read()
client.close()

It's important to close the connection when you're done, and I think the other key part is to set a missing host key policy (you can also use paramiko.WarningPolicy()).

RickardDahlstrand127

I'm getting crashes now and then when using paramiko, it's a pity since it would be such a great addition to the toolset. When I run this script I get a crash on every connect. I suspect memory issues.

https://gist.github.com/rickarddahlstrand/edc7d6af57de4f42162b

Kind regards, Rickard.

omz

The basic problem is that Pythonista crashes if there are threads still running when your script finishes or an exception occurs. Unfortunately, this can happen pretty easily with paramiko if you don't make absolutely sure that every connection is closed under all circumstances.

In this specific example, you get an exception because your port parameter is a string, but an integer is expected.

I've modified your script a little bit to make it more robust. Essentially, I've wrapped the command loop in a try-except-finally statement that makes sure that all connections are closed, even when an exception occurs.

I've also added exit and EOF commands (the latter is triggered when you use the Stop button), to make it possible to get out of the loop.

https://gist.github.com/d608c0469a66ce745c55

RickardDahlstrand127

Ha! And all I could do was to cry memory issues.. :)

Here is the updated src with int-port number. Thanks for all the error checking, I will be using it in the future.

https://gist.github.com/rickarddahlstrand/edc7d6af57de4f42162b

Westacular129

Thanks for the assistance here. I was able to get things working.

One other issue, however, is how slow it is to connect using public key authentication. I did some searching, and found http://stackoverflow.com/questions/10588535/slow-public-key-authentication-with-paramiko and I can confirm that the key length is the issue: with a 1024-bit key, authentication takes a fraction of a second. A 2048-bit key takes 50 seconds (on my iPad 3).

(Helpful tip: Calling
paramiko.common.logging.basicConfig(level=paramiko.common.DEBUG)
enables verbose output analogous to ssh -vv)

pattulus

Ole was so nice to help me with upload script for sending an image to blog. My last obstacle is that I can't get Paramiko to create subfolders in my uploads folder (c.f. "uploads/2013/08").

I put the question on StackOverflow, but since it's likely that the problem with my code is iOS related my hopes aren't high.

Here's the full story: http://stackoverflow.com/questions/18047808/sftp-upload-via-python-and-pythonista-with-paramiko-cant-create-directory-subd

If anyone here can help, I'd be one step closer to get my mobile blogging going.

ccc

What happens if you change;
mkdir_p(os.path.split(remoteFilePath))
to:
mkdir_p(sftp, os.path.split(remoteFilePath))
or:
sftp.mkdir(os.path.split(remoteFilePath))

In the first alternative you are calling yourself. Recursion is when a function calls itself. E.g. Mkdir_p() calls mkdir_p(). I doubt this is what you want but it is difficult to tell.

In the second alternative, you are trying to make the directory on the remote machine which I believe is your goal. If so, I am unclear why you want/need os.path.split().

pattulus

I think I had an error in the script, since somehow remoteFilePath sneaked into the definition where only the placeholder remote_directory should be.

@ccc I tried your alternations but had no luck so far (see errors in the gist):

I also made a gist to explain better what I'm after: https://gist.github.com/pattulus/bf20b63b457a259752ed

At the moment I only have a mix and match wisdom about Python. Hopefully in 6 months everything is clearer.

UPDATE: cclauss (is it you @ccc ?) fixed it for me. I can now delete the quick and dirty fix I setup (- a cronjob which creates the folder each month).

ccc

ccc == cclauss ... Keep the flowers but send the beer!!