從 CloudFormation::Init 呼叫時,多使用者 rvm gem 安裝失敗
我採用了一個 Amazon Linux AMI(基於 CentOS)並以多使用者方式安裝了 RVM (1.10.3)(請參閱下面的 {1})。我用它來安裝 ruby 1.9.3-p125、rubygems 1.8.17 和 bundler 1.1 作為我將要使用實例的大多數事情的基線要求。
我已經將該實例擷取到 AMI,現在通過 CloudFormation 使用一些 CloudFormation::Init 命令啟動它。其中之一是使用 s3cmd 從 S3 中拉下一個私有 gem,下一個失敗的 gem 是安裝該 gem。它失敗並顯示錯誤消息
2012-03-15 16:53:20,201 [ERROR] Command 20_install_gems (/usr/local/rvm/rubies/ruby-1.9.3-p125/bin/gem install ./*.gem) failed 2012-03-15 16:53:20,202 [DEBUG] Command 20_install_gems output: /usr/local/rvm/rubies/ruby-1.9.3-p125/bin/gem:12:in `require': no such file to load -- rubygems (LoadError) from /usr/local/rvm/rubies/ruby-1.9.3-p125/bin/gem:12
現在,這發生在 cfn-init 執行期間 - 我假設但尚未檢查,cfn-init 正在與 ec2-user 不同的環境執行(實例上沒有其他使用者)。
如果我
gem install mygem.gem
在互動式會話中執行,那麼效果很好。所以,我的問題真的是,我應該怎麼做才能使它起作用
cfn-init
?我是否將 rvm 正確設置為多使用者?我已經確認 cfn-init 正在以 root 使用者身份執行,其環境受限。我應該如何獲取
/etc/profile.d/rvm.sh
root 的會話?{1} 我的半自動 rvm 安裝步驟(以 ec2 使用者身份在互動式會話中執行):
sudo bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer ) sudo gpasswd -a ec2-user rvm # iconv-devel is baked into centos' glibc sudo yum install -y autoconf automake bison bzip2 gcc-c++ git libffi-devel libtool libxml2-devel libxslt-devel libyaml-devel make openssl-devel patch readline readline-devel zlib zlib-devel source /etc/profile.d/rvm.sh rvm list known # in a new session: rvm install ruby-1.9.3-p125 rvm use 1.9.3 --default gem update --system # gems required by public_web-awareness gem install aws-sdk bundler cocaine sinatra echo -e "gem: --no-ri --no-rdoc\n" > /home/ec2-user/.gemrc # delete unnecessary documentation files rm -rf `gem env gemdir`/doc sudo -s sudo echo -e "gem: --no-ri --no-rdoc\n" > /etc/skel/.gemrc sudo echo -e "gem: --no-ri --no-rdoc\n" > /etc/gemrc # ctrl + d out of the sudo session
一些環境資訊:
[ec2-user@ip ~]$ echo $PATH /usr/local/rvm/gems/ruby-1.9.3-p125/bin:/usr/local/rvm/gems/ruby-1.9.3-p125@global/bin:/usr/local/rvm/rubies/ruby-1.9.3-p125/bin:/usr/local/rvm/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/opt/aws/bin:/home/ec2-user/bin [ec2-user@ip ~]$ echo $GEM_HOME /usr/local/rvm/gems/ruby-1.9.3-p125 [ec2-user@ip ~]$ echo $GEM_PATH /usr/local/rvm/gems/ruby-1.9.3-p125:/usr/local/rvm/gems/ruby-1.9.3-p125@global [ec2-user@ip ~]$ echo $BUNDLE_PATH [ec2-user@ip ~]$ gem list *** LOCAL GEMS *** aws-sdk (1.3.6) bundler (1.1.0) cocaine (0.2.1) httparty (0.8.1) json (1.6.5) multi_json (1.1.0) multi_xml (0.4.1) nokogiri (1.5.1, 1.5.0) rack (1.4.1) rack-protection (1.2.0) rake (0.9.2) sinatra (1.3.2) tilt (1.3.3) uuidtools (2.1.2) yamler (0.1.0)
所以答案在於在 CloudFormation::Init 期間,
/opt/aws/bin/cfn-init
由 root 使用者在精簡的環境中執行,並/bin/sh
用作其 shell 而不是/bin/bash
. 在過去十年左右的時間裡,我主要是一個 Windows 人,我最初並沒有意識到(記住!)這一點。我嘗試了各種方法,但有效的方法是改編自ScoutApp 的部落格:更改 CloudFormation::Init 元數據
commands
,為它們添加前綴bash -l -c '
和後綴'
(例如gem install foo
變成bash -l -c 'gem install foo'
.