使用Ansible安装Bundler gem

34

我正在使用Ansible在我的VPS上安装Bundler。

我已经设置好了rbenv,全局ruby版本是2.1.0。

如果我以root身份通过SSH登录服务器并运行gem install bundler,它将完美地安装。

我尝试了以下三种使用Ansible安装Bundler gem的方法,这三种方法都没有产生错误,但是当我通过SSH登录并运行gem list时,找不到Bundler。

尝试1:

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

尝试2:

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

尝试三:

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

我还尝试了最后一次尝试,使用user_install=yesuser_install=no,但都没有任何区别。

有什么想法可以通过Ansible正确安装Bundler吗?

我已经在做了一段时间了,我安装了一个Ruby版本:2.1.0,并发现rbenv的shims目录中没有bundle的虚拟链接。

bundle的虚拟链接应该在那里吗?当我运行sudo gem list时,它被列出,但当我运行gem list时却没有被列出,所以我感到困惑为什么capistrano找不到bundle命令。

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

有任何想法吗?

所以,我认为我遇到的两个主要问题是:

  1. 为什么只有当我运行 sudo gem list 时,bundler 才可见?

  2. 我的部署出现了以下错误信息:

    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
    

    这是我的$PATH:

    /usr/local/rbenv/shims:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
    
    为什么无法找到 bundle?

为什么无法找到 bundle?


我发现运行 gem list 命令无法显示 Bundler,但是使用 sudo gem list 命令可以。为什么会这样?Bundler 应该放在哪里才能让 Capistrano 使用它? - rctneil
6个回答

50
问题在于,通过ansible运行gem install bundler时,您没有正确初始化rbenv,因为rbenv init.bashrc.bash_profile中运行。因此,使用的gem命令是系统命令,而不是安装为rbenv shim的命令。因此,每当您安装一个gem时,它会被系统范围内安装,而不是在您的rbenv环境中。
要使rbenv正确初始化,您必须执行bash本身,并明确声明它是登录shell,以便读取其初始化文件:
ansible your_host -m command -a 'bash -lc "gem install bundler"' -u your_rbenv_user 

如果您真的希望以root身份执行此操作,请省略-u your_rbenv_user部分。

如果上述命令有效,您可以轻松地将其转换为playbook动作:

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

很繁琐,但这是我目前找到的唯一方法。


1
嘿,太好了!那很有道理,而且它正常工作。又解决了另一部分问题。接下来是要尝试弄清楚为什么capistrano在部署时找不到bundle命令,但我认为问题可能沿着同样的方向。 - rctneil
2
-l:告诉bash表现得像是通过登录shell调用的 / -c:要执行的命令。它在man bash的第一页上 :) - leucos
1
抱歉,我确实是这个意思。谢谢! - rctneil
1
实际上这非常有帮助!让我对Vagrant的厌恶稍微减轻了一点。 :) 再次感谢。 - Petr Cibulka
1
很好。从ansible 2.x开始,请使用 become_user 而不是 sudo_user - cdmo
显示剩余4条评论

16

自 Ansible 1.3 版本以来,以下原生解决方案成为可能:

- name: requirements for installing gems
  apt:
    name: {{ item }}
  with_items:
    - ruby
    - ruby-dev
    - make

- name: install gem with proper $PATH
  gem:
    name: xyz
    user_install: no

提及user_install参数!此外,由bundler安装的一些依赖项可能需要以下进一步的包依赖关系:

  • zlib1g-dev

谢谢,这对我很有帮助。 - Jean Guzman
最佳答案在那里。 - ipeacocks
user_install: no 仅适用于系统范围的安装。 - TomDogg
@ThomasSteinbach 我可以添加Gemfile而不是单个gem吗?我基本上想执行 bundle install - Nikhil Wagh

2

当我试图以另一个用户身份运行命令时,我遇到了类似的环境问题。正如这个功能请求中提到的那样,你有两个选项可以在登录shell(会加载用户环境)中执行你的命令。例如,我想以rails用户的身份安装bundler:

- name: Install Bundler
  shell: gem install bundler
  sudo_user: rails -i

或者

- name: Install Bundler
  command: sudo -iu rails gem install bundler

0

这个对我有用:

- name: rubygems | install bundler
  shell: gem install bundler

- name: rbenv | rehash
  shell: RBENV_ROOT={{ rbenv_root }} rbenv rehash

有时在系统上安装了bundler和rbenv之后,您需要通过运行rbenv rehash来更新$PATH。我刚刚尝试了使用ansible做同样的事情,它也起作用了。重新散列后,Bundler可以在我的$PATH中使用。

0

我是这样让它工作的:

- name: Install jekyll and bundler                                                                                                                      
  become_user: bob                                                                                                                    
  gem:                                                                                                                                                  
    name: "{{ item }}"                                                                                                                                  
  environment:                                                                                                                                          
    GEM_HOME: /home/bob/gems                                                                                                          
    PATH: $PATH:/bin/:/usr/bin/:/home/bob/gems/bin                                                                                    
  with_items:                                                                                                                                           
    - jekyll                                                                                                                                            
    - bundler 

bob替换为您的本地用户。

然后使用相同的原则与bundler模块。

- name: Install Gems                                                                                                                                    
  become_user: bob                                                                                                                     
  bundler:                                                                                                                                              
    gemfile: /home/bob/Gemfile                                                                                          
    state: present                                                                                                                                      
  environment:                                                                                                                                          
    GEM_HOME: /home/bob/gems                                                                                                           
    PATH: $PATH:/bin/:/usr/bin/:/home/bob/gems/bin

0

使用 Ansible 安装 bundler 最干净、最快捷的方法是:

只需使用 https://github.com/zzet/ansible-rbenv-role 角色安装 rbenv,并配置其插件,例如(显然,除了插件之外还有更多参数需要配置):

rbenv_plugins:
- { name: 'ruby-build',
    repo: 'https://github.com/rbenv/ruby-build.git',
    version: master }
- { name: 'rbenv-default-gems',
    repo: 'https://github.com/rbenv/rbenv-default-gems.git',
    version: master }

包含的插件rbenv-default-gems将在您指定版本的ruby安装过程中默认添加bundler并将其安装到正确的目录中。
然后请确保bundlerPATH中。
就是这样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接