2011-09-29 12 views
32

Ho un server di gestione temporanea con Ruby e Ruby Enterprise installati. Come standard Ruby si rifiuta di installare una gemma critica, ho bisogno di impostare $ PATH in modo che ruby ​​/ gem/rake/etc. fare sempre riferimento alle versioni REE. E poiché utilizzo Capistrano per distribuirlo alle nostre macchine, ho bisogno di farlo a Capistrano.Capistrano: Posso impostare una variabile di ambiente per l'intera sessione cap?

Come è possibile impostare una variabile di ambiente una volta e mantenerla per tutta la sessione Capistrano?

1) È facile da eseguire nei file bashrc, ma Capistrano non legge i file bashrc.

2) userei di Capistrano

default_environment['PATH'] = 'Whatever' 

ma Capistrano utilizza queste variabili d'ambiente come

env PATH=Whatever command arg ... 

e che stanno perse ogni volta che una nuova shell è filata all'interno dell'eseguibile passato a Env. Come quando usi sudo. Che è un pò importante:

[[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) E non posso usare il comando bash di esportazione, in quanto questi si perdono troppo - Capistrano sembra avviare una nuova shell per ogni comando (o qualcosa di simile), e che è perduto, anche:

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

4) ho provato scherzi con Capistrano di: shell e: opzioni PTY pure (e in combinazione con altri approcci), ma senza fortuna nemmeno lì.

Quindi, qual è il modo giusto per farlo? Questo sembra un compito così basilare che dovrebbe esserci un modo davvero semplice per realizzarlo, ma sono fuori dalle idee. Chiunque?

Grazie in anticipo!

risposta

5

Penso che tu abbia in realtà 2 problemi:

1) Si desidera modificare il percorso sul host remoto (s).

Alter/impostare il percorso nel .bashrc sul vostro host remoto (s) ed eseguire cap> printenv, se il percorso è giusto, goto 2 #, altrimenti tenta di aggiungere al vostro export BASH_ENV=~/.bashrc/etc/profile (attenzione, ~ /. bashrc verrà quindi eseguito per tutti shell non interattiva per tutti gli utenti)

2) volete sudo per mantenere il vostro PATH

Run visudo sul vostro host remoto (s) e aggiungere:

Defaults  exempt_group = "<your_user>" 
+0

Buona chiamata: non ero a conoscenza del fatto che sudo oscurasse l'ambiente locale. Sembra che l'aggiunta dell'opzione -E corregge la maggior parte dei casi, ma $ PATH è speciale ([riferimento] (http://stackoverflow.com/questions/257616/sudo-changes-path-why)). Ci giocherò un po 'di più e tornerò da te. Saluti! –

9

Se è necessario impostare una variabile sull'host remoto diverso da PATH, è necessario sapere che sshd consente solo determinate variabili di ambiente /etc/profile o ~/.bashrc per impostazione predefinita, per motivi di sicurezza. Come ha detto Lou, è possibile eseguire cap shell e utilizzare il comando cap> printenv oppure è possibile eseguire cap COMMAND=printenv invoke in un unico comando.

Se si vede la variabile quando si ssh nella shell remota normalmente, ma non si vede che nel comando tappo printenv, ecco una soluzione:

  1. Set PermitUserEnvironment yes nel file del server remoto /etc/ssh/sshd_config, e riavviare sshd
  2. Modificare il file ~/.ssh/environment per l'utente remoto che si sta ssh'ing come, e mettere la variabile (s) lì come VARIABLE=value

Ora quelli dovrebbero presentarsi quando lo fai cap COMMAND=printenv invoke

+0

Potrebbe funzionare, ma richiede la modifica delle impostazioni dei privilegi di root. Vedi la mia risposta. –

3

Avevo bisogno di impostare una variabile di ambiente per un compito specifico di lavorare. Il comando "run" consente di passare opzioni che comprendono: ENV:

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

Nel mio caso, ho voluto aggiungere la variabile d'ambiente ad un compito che non ho scritto, così ho usato default_run_options che viene utilizzato da tutte le invocazioni di corsa. Ho aggiunto questo al top della mia Capfile:

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

Ho visto questa soluzione altrove, ma non riesco a farlo funzionare per me - Ottengo un 'NameError: variabile locale non definita o metodo' default_run_options 'per l'errore principale: Object'. Ho messo questa istruzione di assegnazione nella parte superiore del mio 'Capfile', prima del primo' namespace: deploy do' block. Cosa potrei fare diversamente? – sameers

+0

Come stai eseguendo l'attività? Se esegui l'attività cap, dovrebbe definire default_run_options durante il processo di caricamento in modo che sia disponibile al momento in cui arriva al tuo Capfile. Anche con un Capfile a una riga che dice solo default_run_options [: x] = {'y'>> 'z'}, posso eseguire cap shell. –

46

Ho esattamente lo stesso problema, ma credo che questa soluzione è meglio:

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

Questo funziona per me come un fascino.

+0

hmmm, non funziona per me vedi http://stackoverflow.com/questions/16889642/capistrano-environment-variable?lq=1 – juanpastas

+19

In Capistrano 3 è 'set: default_env, {...}' – Confusion

+1

Domanda stupida, ma Sto provando la stessa cosa e non funziona. Ad ogni modo debuggarlo? – codenoob

0

Ho tentato senza successo di usare la tecnica di @brian-deterling, che è abbastanza comunemente usata da altri che hanno discusso di questo ... Forse sto facendo qualcosa di sbagliato, ma nel frattempo ho trovato la gemma dotenv-rails, e ha funzionato molto bene per caricare i valori da un file .env nella root del progetto.

Le istruzioni sul numero Github repo sono piuttosto semplici. Ho aggiunto il Dotenv.load al mio config/application.rb

Problemi correlati