journal of recreational computer science

home

Jenkins + Capistrano + ssh-agent plugin

27 Nov 2013

Ever gotten this nasty message when attempting to use the ssh-agent plugin with capistrano?:

** [deploy:update_code] exception while rolling back: 
Capistrano::ConnectionError, connection failed for: staging43 
(Net::SSH::Authentication::AgentError: unknown response from agent: 30, "\x00\x00\x00\x01\x1E")

This means that:

  • jenkins' implementation of ssh-agent is running on the host attempting to connect to staging43
  • capistrano tries to connect to the forwarded agent on staging43 via Net::SSH
  • Net::SSH can't recognize the what protocol the agent speaks (see the relevant code here).

What's the workaround?

  • Disable ssh-agent (you can remove the plugin, or simply disable it).

20131127a.png

  • Add some code around your actual piece that does deployment:

Drop the following into the execute shell block which runs the deployment task:

eval `ssh-agent`
echo $SSH_AGENT_PID > ssh-agent.pid
ssh-add
bundle exec cap deploy

And then, add another execute shell block:

kill -9 `cat ssh-agent.pid`

20131127b.png

What does the workaround do?

  • It launches ssh-agent for the current user.
  • ssh-agent outputs a bunch of environment variables which then get eval'd into the current shell session.
  • We save one of the variables for later use (the PID).
  • A key is added to the agent (needs to live in ~/.ssh).
  • The actual deployment process gets executed.
  • Regardless of whether that fails or not, the ssh-agent is killed.
comments powered by Disqus