Fabric: Fabric ne transmet pas l'environnement à un shell local comme le fait Invoke

Créé le 11 mai 2018  ·  14Commentaires  ·  Source: fabric/fabric

Considérez cette définition de tâche, enregistrée à la fois sous les noms fabfile.py et tasks.py :

from invoke import task

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

fab make sorties:

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

inv make sorties:

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)

J'ai initialement trouvé cela en essayant d'utiliser fpm qui vérifie la variable PATH pour vérifier que les exécutables dont elle a besoin pour fonctionner existent:

from invoke import task

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

Cela fonctionne avec invoke, mais pas avec 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()

Commentaire le plus utile

Je viens de rencontrer cela aussi. Je faisais c.run('make build') et aucun de mes ENV n'a réussi (en particulier GOPATH qui a provoqué l'échec de la construction). L'ajout du replace_env=False corrigé.

Edit: je vois selon la documentation :

run.replace_env: True, au lieu de False, de sorte que les commandes à distance s'exécutent avec un environnement «propre» et vide au lieu d'hériter d'une copie de l'environnement du processus actuel.

C'était juste un peu déroutant pour moi car j'essayais d'exécuter une commande locale.

Tous les 14 commentaires

J'ai découvert la description de ce comportement. Cependant, cela n'a aucun sens lors de l'exécution de la commande localement

Ceci est typique pour l'exécution de commandes sur des systèmes distants:

$ 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.

On pourrait essayer de passer par toutes les variables d'environnement en collectant tout l'environnement local et en les définissant de l'autre côté, mais il y en a un certain nombre qui devraient être ignorés car ils seraient en conflit avec la valeur appropriée pour le système distant, comme PATH , GOPATH (si vous utilisez le langage Go), TMPDIR , HOME , SSH_AUTH_SOCK , ...

Notez que je parle uniquement de tâches locales. J'ai même découvert un commentaire TODO qui confirme que l'environnement de passage doit être activé par défaut pour les commandes locales.

ah, je vois, ça a du sens

@justinas J'ai fini par utiliser run from invoke pour les tâches locales, je l'importe comme ceci:

from invoke import run as local

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

C'est une facette de # 1752 - l'intention est que local se comporte comme Invoke et préserve l'environnement, et que run se comporte correctement comme SSH et supprime l'env. Cependant, pour le moment, les configurations à l'origine de ce comportement ne sont pas correctement réparties - c'est effectivement un bogue. Nous allons le réparer bientôt.

Merci pour la réponse!

Je suis juste tombé sur le même problème et je voulais juste noter que ce n'est pas seulement l'environnement local qui est rejeté.

Peut-être que vous êtes déjà au courant de ce bogue également.

Pour clarifier, cela n'a pas fonctionné pour moi:

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

Pour le moment, j'ai trouvé cette solution de contournement (pas très propre) que je peux utiliser:

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

Oui, conscient de cela, merci!

Vous pouvez dire run('...', preserve_env=True) pour contourner ce problème pour le moment, IIRC.

preserve_env ne semble pas exister. Peut-être parliez-vous de replace_env=False ?
Cela ne déclenche pas d'erreur, mais l'environnement est toujours rejeté.

PS: J'ai besoin de définir l'environnement pour les tâches distantes, pas locales.

Oui, je voulais dire replace_env et c'est bizarre que cela ne fonctionne pas. Je jetterai un coup d'oeil quand j'arriverai à diviser la configuration entre local / distant (# 1752)

Je viens de rencontrer cela aussi. Je faisais c.run('make build') et aucun de mes ENV n'a réussi (en particulier GOPATH qui a provoqué l'échec de la construction). L'ajout du replace_env=False corrigé.

Edit: je vois selon la documentation :

run.replace_env: True, au lieu de False, de sorte que les commandes à distance s'exécutent avec un environnement «propre» et vide au lieu d'hériter d'une copie de l'environnement du processus actuel.

C'était juste un peu déroutant pour moi car j'essayais d'exécuter une commande locale.

Le problème est toujours là lors de l'exécution de la commande locale. @bitprophet

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

SamuelMarks picture SamuelMarks  ·  3Commentaires

Grazfather picture Grazfather  ·  4Commentaires

jamesob picture jamesob  ·  3Commentaires

bitprophet picture bitprophet  ·  6Commentaires

supriyopaul picture supriyopaul  ·  4Commentaires