Install Bundler gem using Ansible

rctneil picture rctneil · Mar 1, 2014 · Viewed 18.3k times · Source

I am trying to install Bundler on my VPS using Ansible.

I already have rbenv set up and the global ruby is 2.1.0.

If I SSH as root into the server and run gem install bundler, it installs perfectly.

I have tried the following three ways of using Ansible to install the Bundler gem and all three produce no errors, but when I SSH in and run gem list, Bundler is nowhere to be seen.

Attempt 1:

---
- name: Install Bundler
  shell: gem install bundler

Attempt 2:

---
- name: Install Bundler
  shell: gem install bundler

Attempt 3:

---
- name: Install Bundler
  gem: name=bundler
       state=latest

I have also tried the last attempt with user_install=yes and also with user_install=no and neither make any difference.

Any ideas how I can get it to install Bundler correctly via Ansible?

I've been working on this for a little while now and I have 1 ruby version installed: 2.1.0 and ahve found that the shims directory for rbenv does not contain a shim for bundle.

Should a shim for bundle be in there? I'm just getting confused as to why capistrano cannot find the bundle command as it's listed when I run sudo gem list but NOT when I run gem list?

root@weepingangel:/usr/local/rbenv/shims# echo $PATH
/usr/local/rbenv/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
root@weepingangel:/usr/local/rbenv/shims# gem environment
RubyGems Environment:
  - RUBYGEMS VERSION: 2.2.0
  - RUBY VERSION: 2.1.0 (2013-12-25 patchlevel 0) [x86_64-linux]
  - INSTALLATION DIRECTORY: /usr/local/rbenv/versions/2.1.0/lib/ruby/gems/2.1.0
  - RUBY EXECUTABLE: /usr/local/rbenv/versions/2.1.0/bin/ruby
  - EXECUTABLE DIRECTORY: /usr/local/rbenv/versions/2.1.0/bin
  - SPEC CACHE DIRECTORY: /root/.gem/specs
  - RUBYGEMS PLATFORMS:
    - ruby
    - x86_64-linux
  - GEM PATHS:
     - /usr/local/rbenv/versions/2.1.0/lib/ruby/gems/2.1.0
     - /root/.gem/ruby/2.1.0
  - GEM CONFIGURATION:
     - :update_sources => true
     - :verbose => true
     - :backtrace => false
     - :bulk_threshold => 1000
     - :sources => ["http://gems.rubyforge.org", "http://gems.github.com"]
     - "gem" => "--no-ri --no-rdoc"
  - REMOTE SOURCES:
     - http://gems.rubyforge.org
     - http://gems.github.com
  - SHELL PATH:
     - /usr/local/rbenv/versions/2.1.0/bin
     - /usr/local/rbenv/libexec
     - /usr/local/rbenv/shims
     - /usr/local/sbin
     - /usr/local/bin
     - /usr/sbin
     - /usr/bin
     - /sbin
     - /bin
     - /usr/games

Any ideas?

So, I think the two main problems I have:

  1. Why is bundler only visible when I run sudo gem list?

  2. My deploy is saying:

    INFO [18d5838c] Running /usr/bin/env bundle install --binstubs  
    /var/rails_apps/neiltonge/shared/bin --path  
    /var/rails_apps/neiltonge/shared/bundle --without development test
    --deployment --quiet on 188.226.159.96 DEBUG [18d5838c] Command: cd /var/rails_apps/neiltonge/releases/20140301205432 && ( PATH=$PATH
    /usr/bin/env bundle install --binstubs
    /var/rails_apps/neiltonge/shared/bin --path
    /var/rails_apps/neiltonge/shared/bundle --without development test
    --deployment --quiet ) DEBUG [18d5838c]     /usr/bin/env: bundle: No such file or directory
    

    and this is my $PATH:

    /usr/local/rbenv/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
    

Why can't bundle be located?

Answer

leucos picture leucos · Mar 2, 2014

The problem is that, when running gem install bundler via ansible, you're not initializing rbenv properly, since rbenv init is run in .bashrc or .bash_profile. So the gem command used is the system one, not the one installed as a rbenv shim. So whenever you install a gem, it is installed system-wide, not in your rbenv environment.

To have rbenv initialized properly, you must execute bash itself and explicitely state that it's a login shell, so it reads it's initialization files :

ansible your_host -m command -a 'bash -lc "gem install bundler"' -u your_rbenv_user 

Leave the -u your_rbenv_user part if you really want to do this as root.

If the above command works, you can easily turn it into a playbook action :

- name: Install Bundler
  become_user: your_rbenv_user
  command: bash -lc "gem install bundler"

It's cumbersome, but it's the only way I found so far.