Fabric: Fabric no pasa el entorno a un shell local como lo hace Invoke

Creado en 11 may. 2018  ·  14Comentarios  ·  Fuente: fabric/fabric

Considere esta definición de tarea, guardada como fabfile.py y tasks.py :

from invoke import task

<strong i="8">@task</strong>
def make(c):
    c.run('env')

fab make salidas:

PWD=/tmp
SHLVL=1
_=/usr/bin/env

inv make salidas:

LC_ALL=en_US.UTF-8
NVM_DIR=/home/justinas/.nvm
LC_MEASUREMENT=en_US.UTF-8
LC_PAPER=en_US.UTF-8
LC_MONETARY=en_US.UTF-8
<...> (lots of stuff in my environment)

Inicialmente encontré esto cuando intenté usar PATH para verificar que los ejecutables que requiere para funcionar existen:

from invoke import task

<strong i="22">@task</strong>
def make(c):
    c.run('fpm -s dir -t rpm -C dist --name somename .')

Esto funciona con invoke, pero no con fab.

justinas<strong i="26">@js</strong>:/tmp$ fab make
{:timestamp=>"2018-05-11T13:11:26.218874+0300", :message=>"Need executable 'rpmbuild' to convert dir to rpm", :level=>:error}
justinas<strong i="27">@js</strong>:/tmp$ inv make
{:timestamp=>"2018-05-11T13:11:29.967762+0300", :message=>"Created package", :path=>"somename-1.0-1.x86_64.rpm"}
Bug Connection Needs investigation run()

Comentario más útil

También me encontré con esto. Estaba haciendo c.run('make build') y ninguno de mi ENV se superó (específicamente GOPATH, que causó que la compilación fallara). Agregar el replace_env=False solucionó.

Editar: veo de acuerdo con los documentos :

run.replace_env: Verdadero, en lugar de Falso, para que los comandos remotos se ejecuten con un entorno 'limpio' y vacío en lugar de heredar una copia del entorno del proceso actual.

Fue un poco confuso para mí ya que estaba tratando de ejecutar un comando local.

Todos 14 comentarios

Descubrí la descripción de este comportamiento. Sin embargo, no tiene sentido cuando se ejecuta el comando localmente

Esto es típico para ejecutar comandos en sistemas remotos:

$ env | wc -l
      41
$ ssh testdeploy01.ec2.st-av.net env | wc -l
      14
$ ssh testdeploy01.ec2.st-av.net grep Env /etc/ssh/sshd_config
AcceptEnv LANG LC_*
         Specifies what environment variables sent by the client will be copied into
         the session's environ(7).  See SendEnv in ssh_config(5) for how to configure
         the client.  The TERM environment variable is always sent whenever the
         client requests a pseudo-terminal as it is required by the protocol.  Vari-
         ables are specified by name, which may contain the wildcard characters `*'
         and `?'.  Multiple environment variables may be separated by whitespace or
         spread across multiple AcceptEnv directives.  Be warned that some environ-
         ment variables could be used to bypass restricted user environments.  For
         this reason, care should be taken in the use of this directive.  The default
         is not to accept any environment variables.

Se podría intentar pasar a través de todas las variables de entorno recopilando todo el entorno local y configurándolas en el otro lado, pero hay bastantes números que deberían ignorarse porque entrarían en conflicto con el valor apropiado para el sistema remoto, como PATH , GOPATH (si usa el idioma Go), TMPDIR , HOME , SSH_AUTH_SOCK , ...

Tenga en cuenta que estoy hablando únicamente de tareas locales. Incluso descubrí un comentario TODO que confirma que el entorno de paso debe estar activado de forma predeterminada para los comandos locales.

ah, ya veo, tiene sentido

@justinas Terminé usando ejecutar desde invocar para tareas locales, lo importo así:

from invoke import run as local

<strong i="7">@task</strong>
def test(c):
    local('ls')

Esta es una faceta de # 1752: la intención es que local comporte como Invocar y conservar el env, y que run comporte correctamente como SSH y descarte el env. Sin embargo, en este momento, las configuraciones que impulsan este comportamiento no están divididas correctamente; de ​​hecho, es un error. Lo arreglaremos pronto.

¡Gracias por la respuesta!

Me encontré con el mismo problema y solo quería señalar que no es solo el entorno local lo que se descarta.

Quizás ya esté al tanto de este error.

Para aclarar, esto no funcionó para mí:

<strong i="8">@task</strong>
def test(c):
    c.run('echo $ENV', env={'ENV': 'production'}) # no output

Por el momento, encontré esta solución (no muy limpia) que puedo usar:

<strong i="12">@task</strong>
def test(c):
    with c.prefix('ENV=production'):
        c.run('echo $ENV') # prints "production"

Sí, consciente de eso, ¡gracias!

Puede decir run('...', preserve_env=True) para solucionar eso por ahora, IIRC.

preserve_env no parece existir. ¿Quizás te estabas refiriendo a replace_env=False ?
Eso no desencadena un error, pero el entorno aún se descarta.

PD: necesito configurar el entorno para tareas remotas, no locales.

Sí, me refiero a replace_env y es extraño que eso no funcione. Echaré un vistazo cuando pueda dividir la configuración entre local / remoto (# 1752)

También me encontré con esto. Estaba haciendo c.run('make build') y ninguno de mi ENV se superó (específicamente GOPATH, que causó que la compilación fallara). Agregar el replace_env=False solucionó.

Editar: veo de acuerdo con los documentos :

run.replace_env: Verdadero, en lugar de Falso, para que los comandos remotos se ejecuten con un entorno 'limpio' y vacío en lugar de heredar una copia del entorno del proceso actual.

Fue un poco confuso para mí ya que estaba tratando de ejecutar un comando local.

El problema sigue ahí cuando se ejecuta el comando local. @bitprophet

¿Fue útil esta página
0 / 5 - 0 calificaciones