从 CloudFormation::Init 调用时多用户 rvm gem 安装失败

从 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,失败的那个。它失败并显示错误消息

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-user 身份在交互式会话中运行):

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)

答案1

因此,答案在于,在 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'

相关内容