How to Instruct Capistrano 3 to Load My Shell Environment Variables Set at Remote Host

Bundler: You are trying to install in deployment mode after changing your Gemfile

The error message you're getting regarding Gemfile.lock may be because your Gemfile and Gemfile.lock don't agree with each other. It sounds like you've changed something in your Gemfile since you last ran bundle install (or update). When you bundle install, it updates your Gemfile.lock with any changes you've made to Gemfile.

Make sure you run bundle install locally, and check-in to source control your newly updated Gemfile.lock after that. Then try deploying.

Edit: As recognised in the comments, a conditional in the Gemfile resulted in a valid Gemfile.lock on one platform, invalid on another. Providing a :platform flag for these platform-dependent gems in the Gemfile should solve the asymmetry.

Capistrano error : could not connect to ssh-agent

OK so I had the same issue, and I spent way too long working out exactly what is happening here, and the upshot is -

  • for ruby on windows, you must run pagent, not ssh-agent, for Capistrano and agent forwarding to work - in fact pretty much any tool that uses the Ruby net-ssh library on Windows.

And I dont think that will change, at least not for a while.

Agent Forwarding

See An Illustrated Guide to SSH Agent Forwarding for more about agent forwarding, and how the key challenge ends back up on our workstation.

Terminology

  • workstation - the machine (Windowa server/desktop/laptop) our SSH
    client software is running from, and, most importantly, our PKI
    private key is stored on (with or without a passphrase)

  • deployment node - the target of our Capistrano deployment task, most
    like defined in the 'server' key in our config/deploy.rb, or
    config/deploy/.rb file

  • git repo - where we will pull the code from, first queried via "git
    ls-remote" - we will access this git repo via SSH, and the deployment
    node will use agent forwarding to pass the key challenge back to the
    workstation

  • SSH client software - how we reach out to sshd on remote servers, and
    which has access to our private key. Might be putty, an OpenSSH ssh
    client or the net-ssh library in Ruby.

Setup

I have a Windows 7 workstation box, with Git-Bash, and its OpenSSH ssh client, plus the script from Joe Reagle that sets up some environmental variables that say which port and pid the ssh-agent is operating on.

I also have Putty and Pageant, but I focussed, initially, on just the OpenSSH/Git-Bash tools.

I have set up passwordless ssh from the workstation to the deployment node, I have the ssh-agent running, I have my key added through ssh-add, and I have my public key registered as a read-only access key to the git repo.

Basics

So we are trying to use SSH agent forwarding to have Capistrano pull from our Git repo onto our deployment node.

Now we can test this all ourselves by setting up our public SSH key on the deployment node and using, say, the OpenSSH ssh client, to confirm we have passwordless ssh working. Then we can setup ssh-agent by

  1. starting ssh-agent and setting the SSH_AUTH_SOCK and SSH_AGENT_PID as required.
  2. adding our private key to the ssh-agent via ssh-add
  3. add our public key as an authorised key to the git repo
  4. ssh to the deployment node, and from there do a "git ls-remote git@" (or a ssh -T git@)

If everything is setup correctly, this will all work, and so we will think "ok I can do a 'cap deploy:check'" - and it will fail.

What Went Wrong

We will get an error

"Error reading response length from authentication socket"

Who is telling us this ? It isnt immediately clear, but it

  • isn't the git repo

  • it isnt the git client on the deployment node

  • it isnt the sshd daemon on the deployment node, that wants to pass the key challenge back to the workstation.

Its the Ruby ssh client library on the workstation.

How do we know this

In the ssh_options hash in the deploy.rb file, we add the following :
verbose: :debug

When we do this we see this message

  • Pageant not running.

Why is Capistrano trying to use Pageant instead of ssh-agent

When running via Capistrano, the ssh client is different to the one you used when verifying things by hand.

When verifying by hand, it was an OpenSSH ssh client. Now it is the net-ssh library in Ruby.

And on Windows, net-ssh has these lines

if Net::SSH::Authentication::PLATFORM == :win32
require 'net/ssh/authentication/pageant'
end

or

case Net::SSH::Authentication::PLATFORM
when :java_win32
require 'net/ssh/authentication/agent/java_pageant'
else
require 'net/ssh/authentication/agent/socket'

So loading pageant is hard-coded into net-ssh. It doesnt even try to see if you are running under a unix-like shell (like git-bash or cygwin), and to then use the unix-domain ssh-agent SSH_AUTH_SOCK

At present net-ssh doesnt try to open a unix-domain named socket. In theory I think it could, through the UNIXSocket class in the stdlib. But I haven't experimented with that on a Windows machine yet.



Related Topics



Leave a reply



Submit