Tuesday, April 23, 2013

Don't dare prompt me

At Netflix, we've been trying to come up with an effective way to distribute the Gradle wrapper (more on that in another post), and the solution we're going for is to check it into a git repo, which can then be cloned locally or referenced as a submodule for CI builds. So, when we're constructing our wrapper and pointing it to a custom distribution of Gradle we need to perform git commands. Luckily Andrew Oberstar created a eponymous Gradle plugin called gradle-git, which wraps JGit. We already started to use it to publish javadocs to gh-pages in the Netflix OSS projects. In this case, I started to use it to check the new wrapper into a repo, only to find out that I was being prompted for my passphrase.

It's easy to forget that one's SSH private key has a passphrase on it, because most apps indirectly ask ssh-agent or Pageant for the key. (Note: I almost forgot my passphrase, please go and check that you still remember yours.) When I say most apps, I mean every possible app except JGit.  When JGit was written it appears that it was abstracting out the underlying implementation of SSH, but generally uses JSch to keep everything in the JVM. The problem is the JGit seems to use some defaults that bring a Swing UI to prompt a user for their passphrase every time it instantiates a session. This might make sense in an IDE, but in a CI server that is ridiculous.

A quick Google search shows that the creators of JSch figured this out and wrote jsch-agent-proxy. Great, all I have to do is wire that in and prest-o change-o, I'll no longer be prompted. Nope. I searched high and low and couldn't find an example of someone configuring jsch-agent-proxy with JGit. Some more research showed that JGit in all it's lovely abstraction layers hides the parts of JSch that I need to plug in jsch-agent-proxy.

Here's my implementation that connects the JSch under JGit to use jsch-agent-proxy:

Loading ....

Most of this code comes from jsch-agent-proxy's JSchWithAgentProxy example. jsch-agent-proxy has an impressive set of implementations. It can use Unix Sockets or JNA, or talk to ssh-agent or Pageant. Given how easy the JGit API is to use, I expect some interesting Java-based utilities to come out in the next year.