Капистрано: Могу ли я установить переменную окружения для всего сеанса кепки?

У меня есть промежуточный сервер с установленными стандартными Ruby и Ruby Enterprise. Поскольку стандарт Ruby отказывается устанавливать критический камень, мне нужно установить $PATH так, чтобы ruby ​​/gem/rake/etc. всегда ссылайтесь на версии REE. И поскольку я использую Capistrano для развертывания на наших машинах, мне нужно сделать это в Capistrano.

Как установить переменную среды один раз и сохранить ее на протяжении всей сессии Capistrano?

1) Это легко сделать в файлах bashrc, но Capistrano не читает файлы bashrc.

2) Я использовал бы

Capistrano <
default_environment['PATH'] = 'Whatever'

но Capistrano использует эти переменные среды, например

env PATH=Whatever command arg ...

и они теряются всякий раз, когда другая оболочка создается в исполняемом файле, переданном env. Например, когда вы используете sudo. Что очень важно:

[[email protected] trunk]$ env VAR=hello ruby -e "puts ENV['VAR']"
hello
[[email protected] trunk]$ env VAR=hello sudo ruby -e "puts ENV['VAR']"
nil

3) И я не могу использовать команду экспорта bash, поскольку они тоже потеряны. Кажется, что Capistrano запускает новую оболочку для каждой команды (или что-то в этом роде), и это тоже потеряно:

cap> export MYVAR=12
[establishing connection(s) to xxx.xxx.xxx.xxx]
cap> echo $MYVAR
 ** [out :: xxx.xxx.xxx.xxx] 
cap> 

4) Я также попытался испортить опции Capistrano: shell и: pty (и в сочетании с другими подходами), но также не повезло.

Итак - какой правильный способ сделать это? Это похоже на такую ​​базовую задачу, что должен быть действительно простой способ ее достижения, но у меня нет идей. Кто-нибудь?

Спасибо заранее!

Ответ 1

У меня точно такая же проблема, но я думаю, что это решение лучше:

set :default_environment, { 
  'env_var1' => 'value1',
  'env_var2' => 'value2'
}

Это работает для меня как шарм.

Ответ 2

Если вам нужно установить переменную на удаленном хосте, отличном от PATH, вы должны знать, что по умолчанию для sshd разрешены только определенные переменные среды /etc/profile или ~/.bashrc по соображениям безопасности. Как сказал Лу, вы можете сделать cap shell и использовать команду cap> printenv, или вы можете сделать cap COMMAND=printenv invoke в одной команде.

Если вы видите переменную, когда вы ssh в удаленной оболочке нормально, но вы не видите ее в команде cap printenv, здесь одно решение:

  • Установите PermitUserEnvironment yes в файл удаленного сервера /etc/ssh/sshd_config и перезапустите sshd
  • Отредактируйте файл ~/.ssh/environment для удаленного пользователя, в котором вы ssh'ing, и поместите здесь свою переменную как VARIABLE=value

Теперь они появятся, когда вы сделаете cap COMMAND=printenv invoke

Ответ 3

Я думаю, что у вас есть 2 проблемы:

1) Вы хотите изменить PATH на своем удаленном хосте.

Измените/установите путь в своем .bashrc на своем удаленном хосте и запустите cap> printenv, если ваш путь прав, перейдите к # 2, добавьте export BASH_ENV=~/.bashrc к вашему /etc/profile (будьте осторожны, ~/.bashrc будет запускаться для всех неинтерактивных оболочек для всех пользователей)

2) Вы хотите, чтобы sudo сохранял ваш PATH

Запустите visudo на своем удаленном хосте (ов) и добавьте:

Defaults        exempt_group = "<your_user>"

Ответ 4

Мне нужно было установить переменную среды для выполнения конкретной задачи. Команда "run" позволяет передавать параметры, которые включают: env:

run "cmd", :env => { 'name' => 'value' }

В моем случае я хотел добавить переменную окружения к задаче, которую я не писал, поэтому я использовал default_run_options, который используется всеми вызовами запуска. Я добавил это в начало моего Capfile:

default_run_options[:env] = { 'name' => 'value' }

Ответ 5

Я безуспешно пытался использовать технику @brian-defling, которая довольно часто используется другими, которые обсуждали это... Возможно, я делаю что-то неправильно, но между тем я нашел драгоценный камень dotenv-rails, и он работал очень красиво для загрузки значений из файла .env в моем корневом каталоге проекта.

Инструкции по их Github repo довольно прямолинейны. Я добавил Dotenv.load в мой config/application.rb