Easier Capistrano Deploys from GitHub with ssh-agent

One great option for Capistrano deploys out of git is to use an ssh-agent. The agent will forward your own SSH keys from your development machine and make them available during deploys without ever needing to pollute your production servers with your keys. GitHub has a “great getting-started document here”:https://help.github.com/articles/using-ssh-agent-forwarding.

While it’s a great idea, using ssh-agent in practice has left me shrieking profanity at my keyboard on more than one occasion and wondering why the heck I keep getting SSH authentication errors when I *know* I typed my password right that last time. Invariably it’s not a server problem, a network problem, or anything else — it’s just me forgetting to start the agent and add a key.

I don’t end up needing the agent too often, which is why I forget. I finally broke down today and wrote the below snippet into my deploys. It’s not perfect, but it helps remind me what I need to do when I forget:

  task :check_for_ssh_agent do
    pid = ENV["SSH_AGENT_PID"]
    raise %|No ssh-agent active (cannot authenticate to bitbucket without it.) Try running "eval `ssh-agent`; ssh-add".| if pid.nil? or pid == "" or pid.to_i == 0

    begin
      Process.getpgid(pid.to_i)
    rescue Errno::ESRCH
      raise %|The ssh-agent at pid #{pid} has died (cannot authenticate to bitbucket without it.) Try running "eval `ssh-agent`; ssh-add".|
    end

    if `ssh-add -L` =~ /no identities/
      raise %|The ssh-agent at pid #{pid} has no keys. Have you run "ssh-add"?|
    end
  end
  before "deploy:update", "check_for_ssh_agent"

If you drop that in your Capistrano config, it’ll do some rudimentary checking to ensure you’re ready to go and may save you some frustration. Has anyone else come up with a good automated script to prevent these silly errors?