Эластичный бобовый стебель: не удается найти gem bundler (>= 0.a) с помощью исполняемого пакета (Gem::GemNotFoundException)

#ruby-on-rails #ruby #amazon-web-services #rubygems #amazon-elastic-beanstalk

#ruby-on-rails #ruby #amazon-веб-сервисы #rubygems #amazon-elastic-beanstalk

Вопрос:

Это сообщение об ошибке является хорошо известным сообщением об ошибке. (см. https://bundler.io/blog/2019/01/04/an-update-on-the-bundler-2-release.html например.) Хотя я получаю его с новым приложением Elastic Beanstalk с Ruby 2.6.1 и bundler 2.0.1. Ошибка заключается в:

   /opt/rubies/ruby-2.6.1/lib/ruby/site_ruby/2.6.0/rubygems.rb:289:in `find_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)
from /opt/rubies/ruby-2.6.1/lib/ruby/site_ruby/2.6.0/rubygems.rb:308:in `activate_bin_path'
from /opt/rubies/ruby-2.6.1/bin/bundle:23:in `<main>' (ElasticBeanstalk::ExternalInvocationError)
  

Я попытался поместить следующий файл: 01_install_bundler.config в .ebextensions папку:

 container_commands:
  01_install_bundler:
    command: "gem install bundler —-version 2.0.1"
  

Хотя это никогда не запускается, потому что, если я посмотрю на приведенную выше ошибку, я увижу, что это происходит на этом этапе процесса развертывания:

 .../AppDeployStage0/AppDeployPreHook/10_bundle_install.sh] : Activity failed.
  

(т.е. во время bundle install команды скрипта AppDeployPreHook). Смотрите https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/custom-platform-hooks.html для справки о платформах.

Я почти уверен, что если я смогу гарантировать, что используемая версия bundler является по крайней мере версией 2.0.0, то проблем не возникнет. Хотя я не знаю, как я могу это легко указать. На данный момент я подключаюсь по ssh к серверу, чтобы /opt/elasticbeanstalk/hooks/appdeploy/pre/ отредактировать скрипты и поработать с ними. Хотя мне, очевидно, нужен автоматизированный, повторяемый способ сделать это.

Разочаровывает, что ruby 2.6.1 не выбирает версию пакета 2.0.0 по умолчанию. Есть идеи?

==============================

Обновить:

Если я отредактирую файл /opt/elasticbeanstalk/hooks/appdeploy/pre/10_bundle_install.sh

 if [ -f Gemfile ]; then
  echo "running 'bundle install' with Gemfile:"
  cat Gemfile

      gem install bundler    
  if [ -d $EB_APP_STAGING_DIR/vendor/cache ]; then
    bundle install --local
  else
    bundle install
  fi
else
  echo "no Gemfile found! Skipping bundle install stage!"
fi
  

и добавьте gem install bundler (без плюсов), тогда это устраняет проблему, потому что он устанавливает последнюю версию пакета, которая 2.0.1. Для тех, кто хочет знать, как взломать, команды были:

eb ssh

sudo -i

cd /opt/elasticbeanstalk/hooks/appdeploy/pre

vim 10_bundle_install.sh

Проблема с этим решением заключается в том, что оно похоже на взлом, потому что оно не использует .ebextensions . Есть ли более правильный способ исправить это?

Комментарии:

1. Попробовал 10_bundle_install.sh1 взломать, и EB пожаловался, что я не должен пытаться установить Bundler от имени root.

2. @NBarnes, это может быть связано с тем, что при запуске eb deploy вы, вероятно, подключаетесь с помощью aws_access_key и aws_secret_access_key вашей корневой учетной записи AWS. AWS рекомендует использовать для этой цели управление доступом к удостоверениям (IAM). Настроить его не так уж сложно. В разделе IAM -> Users вам просто нужно создать пользователя со следующими разрешениями: AWSElasticBeanstalkFullAccess и ElasticLoadBalancingFullAccess . Затем создайте ключи доступа для этого пользователя и запустите eb deploy вместо этого этот профиль.

3. Основываясь на вашем предложении, я создал нового пользователя с помощью IAM и предоставил им эти два разрешения. Однако я все еще получаю сообщение об ошибке запуска Bundler от имени root. Я сбросил учетные данные в командной строке AWS; cat ~/.aws/config показывает ключи доступа для пользователя, не являющегося пользователем root. РЕДАКТИРОВАТЬ: Возможно, проблема в том, что в приведенном ниже фрагменте файла расширения вы owner установили значение root ?

4. Я не уверен @NBarnes. owner Из root приведенных ниже является владельцем файла. В то время как похоже, что ваша ошибка говорит о том, что пользователь находится root во время выполнения этого файла, а не о том, что сам файл принадлежит root . Если вы выполните поиск в Google «установить пакет от имени root», есть несколько возможных объяснений. И, возможно, ваша среда AWS отличается от моей? Я запускаю Passenger with Ruby 2.6 running on 64bit Amazon Linux/2.9.1

Ответ №1:

Итак, вот программное решение вышеупомянутой проблемы. Создайте приведенный ниже файл в .ebextensions/gem_install_bundler.config :

 files:
  # Runs before `./10_bundle_install.sh`:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/09_gem_install_bundler.sh" :
    mode: "000775"
    owner: root
    group: users
    content: |
      #!/usr/bin/env bash

      EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)
      EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
      # Source the application's ruby, i.e. 2.6. Otherwise it will be 2.3, which will give this error: `bundler requires Ruby version >= 2.3.0` 
      . $EB_SCRIPT_DIR/use-app-ruby.sh

      cd $EB_APP_STAGING_DIR
      echo "Installing compatible bundler"
      gem install bundler -v 2.0.1
  

Затем, когда вы выполните следующий шаг eb deploy , пакет будет обновлен до версии 2.0.1, и вы больше не получите вышеуказанную ошибку.

Дополнительная информация в документах здесь:

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/custom-platform-hooks.html

и здесь:

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/customize-containers-ec2.html#linux-files

Последнее замечание: убедитесь, что вы либо зафиксировали эти изменения перед запуском eb deploy , либо разместили их на стадии и запустили eb deploy --staged . Смотрите: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb3-cli-git.html . Я узнал это на собственном горьком опыте!

Комментарии:

1. я добавил этот файл, но по-прежнему получаю ту же ошибку, странно то, что я не получаю echo, но внутри архива есть .ebextensions/gem_install_bundler.config файл на корневом уровне — есть ли что-то еще, что я должен сделать? Я использую Ruby 2.6.3

2. Если вы не получаете echo , то он вообще не выполняется. Попробуйте переместить echo в качестве первого оператора, который будет выполнен, на случай, если ваши вышеуказанные команды не выполняются.

3. Мне пришлось добавить gem update --system в конце файла, и это устранило проблему 🙂

4. У меня это сработало. В моем конкретном случае мне пришлось установить версию пакета 2.0.2 вместо 2.0.1.

5. «Пользовательские платформенные привязки — это устаревшая функция, которая существует на платформах Amazon Linux AMI. На платформах Amazon Linux 2 пользовательские платформенные хуки в папке /opt/elasticbeanstalk / hooks / полностью прекращены.» docs.aws.amazon.com/elasticbeanstalk/latest/dg /…

Ответ №2:

Вот версия, которая может использоваться в новых версиях платформы Amazon Linux 2, поскольку старые /opt/elasticbeanstalk/hooks/ папки полностью удалены. Он анализирует версию пакета из Gemfile.lock

Этот скрипт будет запущен .platform/hooks/prebuild/01_install_app_bundler.sh , и его необходимо пометить как исполняемый, иначе он завершится ошибкой из-за проблемы с разрешениями ( chmod x 01_install_app_bundler.sh )

 #!/usr/bin/env bash

# Load environment data
EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config platformconfig -k AppStagingDir)
EB_APP_USER=$(/opt/elasticbeanstalk/bin/get-config platformconfig -k AppUser)
EB_APP_DEPLOY_DIR=$(/opt/elasticbeanstalk/bin/get-config platformconfig -k AppDeployDir)

# Set up correct environment
export $(cat /opt/elasticbeanstalk/deployment/env | xargs)

BUNLDER_VER_TO_INSTALL=$(grep -A 1 "BUNDLED WITH" Gemfile.lock | tail -n1 | tr -d ' ')

echo "Installing bundler $BUNLDER_VER_TO_INSTALL"
gem install bundler -v $BUNLDER_VER_TO_INSTALL
  

Я оставил там некоторые неиспользуемые переменные EB_, просто чтобы показать, как их можно определить на обновленной платформе.

Ответ №3:

Я только что увидел этот пост после того, как нашел альтернативное (возможно, более простое) решение: откорректировать bundler до 1.17.3 ( gem unistall bundler вслед за gem install bundler -v 1.17.3 )

Ответ №4:

Вам нужна правильная версия пакета, с помощью которого был сгенерирован файл блокировки. Чтобы узнать эту версию, используйте следующую команду

 $ cat Gemfile.lock | grep -A 1 "BUNDLED WITH"
BUNDLED WITH
   1.17.3