web-dev-qa-db-fra.com

Capistrano: Puis-je définir une variable d'environnement pour toute la session de plafonnement?

J'ai un serveur de stockage intermédiaire avec Ruby Standard et Ruby Enterprise installé. Comme Ruby refuse d'installer une gemme critique, je dois définir $ PATH pour que Ruby/gem/rake/etc. toujours se référer aux versions REE. Et comme j'utilise Capistrano pour déployer sur nos machines, je dois le faire à Capistrano.

Comment puis-je définir une variable d'environnement une fois, et qu'elle persiste tout au long de la session Capistrano?

1) C'est facile à faire dans les fichiers bashrc, mais Capistrano ne lit pas les fichiers bashrc.

2) J'utiliserais celui de Capistrano

default_environment['PATH'] = 'Whatever'

mais Capistrano utilise ces variables d'environnement comme

env PATH=Whatever command arg ...

et ils sont perdus chaque fois qu'un autre shell est créé dans l'exécutable transmis à env. Comme lorsque vous utilisez Sudo. Ce qui est un peu important:

[holt@Michaela trunk]$ env VAR=hello Ruby -e "puts ENV['VAR']"
hello
[holt@Michaela trunk]$ env VAR=hello Sudo Ruby -e "puts ENV['VAR']"
nil

3) Et je ne peux pas utiliser la commande bash export, car elles sont également perdues - Capistrano semble lancer un nouveau shell pour chaque commande (ou quelque chose du genre), et c'est également perdu:

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

4) J'ai essayé de jouer avec les options Capistrano: Shell et: pty également (et en combinaison avec les autres approches), mais pas de chance là-bas non plus.

Alors - quelle est la bonne façon de faire cela? Cela semble être une tâche tellement fondamentale qu'il devrait exister un moyen très simple de l'accomplir, mais je suis à court d'idées. N'importe qui?

Merci d'avance!

33
Xavier Holt

J'ai exactement le même problème, mais je pense que cette solution est meilleure:

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

Cela fonctionne pour moi comme un charme.

49
Peter Lee

Si vous devez définir une variable sur l'hôte distant autre que PATH, sachez que sshd n'autorise que certaines variables d'environnement /etc/profile ou ~/.bashrc par défaut, pour des raisons de sécurité. Comme Lou l'a dit, vous pouvez soit faire cap Shell et utiliser la commande cap> printenv, soit vous pouvez faire cap COMMAND=printenv invoke en une seule commande.

Si vous voyez normalement la variable lorsque vous utilisez ssh dans le shell distant, mais que vous ne la voyez pas dans la commande cap printenv, voici une solution:

  1. Définissez PermitUserEnvironment yes dans le fichier /etc/ssh/sshd_config de votre serveur distant et redémarrez sshd
  2. Editez le fichier ~/.ssh/environment pour l'utilisateur distant sous lequel vous êtes en SSH, et placez votre (vos) variable (s) sous la forme VARIABLE=value

Maintenant, ceux-ci devraient apparaître lorsque vous faites cap COMMAND=printenv invoke

10
bjnord

Je pense que vous avez en fait 2 problèmes:

1) Vous voulez changer le PATH sur vos hôtes distants.  

Modifiez/définissez le chemin dans votre .bashrc sur votre ou vos hôtes distants et exécutez cap> printenv. Si votre chemin est correct, passez à l'étape 2, sinon essayez d'ajouter export BASH_ENV=~/.bashrc à votre /etc/profile (attention, ~/.bashrc sera alors exécuté pour tous les Shell non interactifs pour tous les utilisateurs)

2) Vous voulez que Sudo garde votre PATH

Exécutez visudo sur votre ou vos hôtes distants et ajoutez:

Defaults        exempt_group = "<your_user>"
5
Lou Terrailloune

Je devais définir une variable d'environnement pour qu'une tâche spécifique fonctionne. La commande "run" vous permet de passer des options incluant: env:

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

Dans mon cas, je voulais ajouter la variable d'environnement à une tâche que je n'avais pas écrite. J'ai donc utilisé default_run_options, qui est utilisé par tous les appels de run. J'ai ajouté ceci en haut de mon fichier Capfile:

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

J'ai essayé sans succès d'utiliser la technique de @ brian-deterling, qui est assez utilisée par d'autres qui en ont parlé ... Peut-être que je fais quelque chose de mal, mais en attendant, j'ai trouvé le joyau dotenv-Rails, qui fonctionnait très bien pour charger des valeurs sur un fichier .env dans la racine de mon projet.

Les instructions sur leur Github repo sont assez simples. J'ai ajouté le Dotenv.load à mon config/application.rb

0
sameers