From the Canyon Edge -- :-Dustin
Showing posts with label launchpad. Show all posts
Showing posts with label launchpad. Show all posts

Tuesday, February 5, 2013

ssh-import-id now supports Github!

tl;dr

As of ssh-import-id 3.0, you can now import SSH public keys from both Launchpad and Github using lp:$USER and gh:$USER like this:

$ ssh-import-id lp:kirkland gh:cmars
2013-02-05 17:54:15,638 INFO Authorized key ['4096', 'd3:dd:e4:72:25:18:f3:ea:93:10:1a:5b:9f:bc:ef:5e', 'kirkland@x220', '(RSA)']
2013-02-05 17:54:15,647 INFO Authorized key ['2048', '69:57:f9:b6:11:73:48:ae:11:10:b5:18:26:7c:15:9d', 'kirkland@mac', '(RSA)']
2013-02-05 17:54:22,125 INFO Authorized key ['2048', '84:df:01:9f:da:d3:ef:7d:a0:44:17:ff:ab:30:15:22', 'cmars@github/2114943', '(RSA)']
2013-02-05 17:54:22,134 INFO Authorized key ['2048', 'ab:6a:0c:99:09:49:0b:8f:2a:12:e2:f3:3d:c7:a9:79', 'cmars@github/3263683', '(RSA)']
2013-02-05 17:54:22,135 INFO Authorized [4] new SSH keys
This is now available in Ubuntu Raring 13.04, backported to all other supported Ubuntu releases in this PPA, in the upstream source tarballs, and now installable through pip from pypi!

Background

It's been almost 3 years now since I introduced ssh-import-id here on this blog.  I have a Google Alert setup to watch ssh-import-id and I'm delighted to see that it seems to be quite popular and heavily used!

As a brief reintroduction, ssh-import-id is similar to the ssh-copy-id command.  Whereas ssh-copy-id pushes your public key into a remote ~/.ssh/authorized_keys file, ssh-import-id pulls a public key into the local ~/.ssh/authorized_keys.  Especially in cloud instances, it's a great way to securely, easily, and conveniently retrieve and install your own SSH public key, or perhaps that of a friend or colleague.

When I initially wrote it, it was really just a simple shell script wrapper around wget, with some error checking, that would pull public keys over an SSL connection from Launchpad.net.  All of my network friends and colleagues had active, authenticated accounts at Launchpad.net, and everyone had to upload their public GPG keys and public SSH keys to Launchpad in order to get any work done.  This was really easy, since all keys are available as flat text at a very predictable URL pattern: https://launchpad.net/~%s/+sshkeys.

I have always wanted ssh-import-id to be able to pull keys from servers other than Launchpad.  The tool has long supported defining a $URL in your environment or in /etc/ssh/ssh_import_id at the system level.  There just aren't really any other good, authenticated SSH public key servers.

Github

A few days ago, my friend and Gazzang colleague Casey Marshall noticed that Github had actually recently added support to their API which exposes public SSH keys!  This was just awesome :-)  It would take a bit of effort to support, though, as the output format differs between Launchpad (raw text) and Github (JSON).

So this past Saturday on a beautiful evening in Austin, TX (when neither of us should really have been hacking), we both independently initiated our own implementation adding support for Github keys in ssh-import-id :-)  A bit of duplicated effort?  Yeah, oh well...  But we both took a similar approach: let's port this puppy from shell to Python so that we can take advantage of JSON parsing (our alternative was awk!).

Python

My approach was pretty elementary...  I basically implemented a line-by-line, function-by-function port from Shell to Python, since I knew, from a regression standpoint, this would be stable, solid code.  But Casey is undoubtedly the better programmer between the two of us :-)  He took a much more Pythonic approach, implementing each of the protocol handlers as sub commands.

Once we caught up with one another online around midnight Saturday night, we realized that we really duplicating efforts.  So we decided to team up on the problem!  Casey had a much more elegant design, complete with a setup.py and uploadable to pypi.python.org.  Meanwhile, I have maintained the source code and the package in Ubuntu for nearly 3 years and I understood the complex set of legacy compatibility I needed to preserve, as well as several years worth of gotchas and bugs-fixed.  So I took Casey's implementation, whole hog, and went to work on a bunch of little things to get it whipped into shape for upload to Ubuntu.

Portability

Given that Github is now supported in addition to Launchpad, there may actually be some interest in the tool beyond Ubuntu.  Non-Ubuntu users can now install ssh-import-id directly from pypi.python.org!

$ sudo pip install ssh-import-id
Downloading/unpacking ssh-import-id
  Running setup.py egg_info for package ssh-import-id
    
Requirement already satisfied (use --upgrade to upgrade): argparse in /usr/lib/python2.7 (from ssh-import-id)
Downloading/unpacking Requests >=1.1.0 (from ssh-import-id)
  Running setup.py egg_info for package Requests
    
Installing collected packages: ssh-import-id, Requests
  Running setup.py install for ssh-import-id
    
    changing mode of /usr/local/bin/ssh-import-id-lp to 775
    changing mode of /usr/local/bin/ssh-import-id to 775
    changing mode of /usr/local/bin/ssh-import-id-gh to 775
  Running setup.py install for Requests
    
Successfully installed ssh-import-id Requests
Cleaning up...

Other New Features

We've added a few other new features in the 3.x series...
  1. We now detect duplicate keys by their size/fingerprint/type, and avoid adding duplicates
  2. We also now support a -r|--remove option, which you can use to prune keys from ~/.ssh/authorized_keys file that were added by ssh-import-id
Please report bugs as you find them here!  And please use StackExchange for questions!  Enjoy ;-)

:-Dustin

Monday, January 16, 2012

Automatically Swapping Launchpad and Bazaar Identities


I've been a Launchpad.net member since 2006-10-11, when I first created an account to add some debugging information and submit a patch to a bug affecting the xserver on iMac G3s and the Ubuntu 6.06 PowerPC LiveCD, which my wife, Kim, used in her 4th grade classroom.  Wow, those were the days!  I see that that bug is still open :-)  I can't imagine that hardware is even functional anymore....is it?


I was thoroughly impressed with the shear elegance, look, feel, and usability of Launchpad.net.  I was a long time user of SourceForge.net and Bugzilla, and had brushed by at least a dozen other bug trackers.  No other bug tracker or source code system could hold a candle to Launchpad, in my opinion.

In my ~4 years at Canonical, Launchpad.net and Bazaar became the cornerstone and foundation of my day to day development and productivity.  I was absolutely thrilled when Launchpad was open sourced (to relatively little fanfare, sadly).


I've filed and fixed a few minor issues, and worked around some others, and leveraged Launchpad for tools of my own (like ssh-import-id).  And today, I still think Launchpad.net and Bazaar are the best combination of bug tracking, source code management, binary package builders, team building, blueprint tracking out there!

I continue to use Launchpad and Bazaar to manage more than two dozen open source projects.  And now, we're also using commercial Launchpad here at Gazzang now, actively committing to both public and private projects every day.

This introduced a new challenge, for me, though.  I want to make ensure that my commits to Bazaar when I'm "at the office" and working on Gazzang projects are correctly credited to my work email address and identity, and otherwise, they're credited to my personal email address.

This email address is stored in ~/.bazaar/bazzar.conf.  For me, the logic is pretty easy...  I generally work from the office where we have a (mostly) static IP address.  I simply run a cronjob every five minutes that checks my external IP address, and updates ~/.bazaar/bazzar.conf accordingly.  Your logic might differ (perhaps time of day, etc.).  Does anyone know how I might perhaps hook bzr to check the project's name at commit time?  Also, any ideas about how to update $DEBEMAIL in a similar manner?  It's an environment variable, so it's pretty hard/impossible to update that in all of my shells and byobu sessions/windows/splits, and the Debian maintainer rejected a few requests to support $DEBEMAIL in ~/.devscripts.  Other ideas?

My script currently looks something like this:

#!/bin/sh
# $HOME/bin/update-email
work_email="dustin.kirkland@work.example.com"
home_email="dustin@home.example.com"

work_ip="10.9.8.7"
current_ip=$(wget -q -O- http://v4.ipv6-test.com/api/myip.php 2>/dev/null)

if [ "$current_ip" = "$work_ip" ]; then
        sed -i -e "s/<.*>/<$work_email>/g" $HOME/.bazaar/bazaar.conf
else
        sed -i -e "s/<.*>/<$home_email>/g" $HOME/.bazaar/bazaar.conf
fi

And it runs in this cronjob:
*/5 * * * *  run-one $HOME/bin/update-email

Suggestions for improvement?  Leave a note!

Enjoy!
:-Dustin

Printfriendly