Amazon-Ec2

從 CloudFormation::Init 呼叫時,多使用者 rvm gem 安裝失敗

  • March 27, 2012

我採用了一個 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.shroot 的會話?

{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'.

引用自:https://serverfault.com/questions/370166