Я взял 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, а следующий, который не работает, - установить этот гем. Сбой с сообщением об ошибке
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
в корневые сеансы?
{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
как его оболочка вместо /bin/bash
. Поскольку последние десять или около того лет я в основном работал с Windows, я сначала этого не осознавал (помните!).
Я пробовал разные вещи, но то, что работало, было адаптировано из Блог ScoutApp: изменить метаданные CloudFormation :: Init commands
поставить перед ними bash -l -c '
и суффикс '
(так например gem install foo
стал bash -l -c 'gem install foo'
.