Fabric: Fabric übergibt die Umgebung nicht wie Invoke an eine lokale Shell

Erstellt am 11. Mai 2018  ·  14Kommentare  ·  Quelle: fabric/fabric

Betrachten Sie diese Aufgabendefinition, die sowohl als fabfile.py als auch als tasks.py gespeichert ist:

from invoke import task

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

fab make Ausgaben:

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

inv make Ausgaben:

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)

Ich fand dies anfangs, als ich versuchte, fpm zu verwenden, das die Variable PATH überprüft, um zu überprüfen, ob die ausführbaren Dateien vorhanden sind, die für die Funktion erforderlich sind:

from invoke import task

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

Dies funktioniert mit invoke, aber nicht mit 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()

Hilfreichster Kommentar

Ich bin auch nur darauf gestoßen. Ich habe c.run('make build') und keiner meiner ENV hat es geschafft (speziell GOPATH, was dazu führte, dass der Build fehlschlug). Das Hinzufügen von replace_env=False Problem behoben.

Bearbeiten: Ich sehe nach den Dokumenten :

run.replace_env: True anstelle von False, sodass Remotebefehle mit einer 'sauberen', leeren Umgebung ausgeführt werden, anstatt eine Kopie der aktuellen Prozessumgebung zu erben.

Es war nur ein bisschen verwirrend für mich, da ich versuchte, einen lokalen Befehl auszuführen.

Alle 14 Kommentare

Ich habe die Beschreibung dieses Verhaltens entdeckt. Es macht jedoch keinen Sinn, den Befehl lokal auszuführen

Dies ist typisch für das Ausführen von Befehlen auf Remote-Systemen:

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

Man könnte versuchen, alle Umgebungsvariablen zu durchlaufen, indem man die gesamte lokale Umgebung sammelt und auf der anderen Seite festlegt, aber es gibt eine ganze Reihe, die ignoriert werden müssten, da sie mit dem entsprechenden Wert für das Remote-System wie PATH Konflikt stehen würden GOPATH (wenn Sie die Go-Sprache verwenden), TMPDIR , HOME , SSH_AUTH_SOCK , ...

Beachten Sie, dass ich nur über lokale Aufgaben spreche. Ich habe sogar einen TODO-Kommentar entdeckt , der bestätigt, dass die Übergabeumgebung für lokale Befehle standardmäßig aktiviert sein sollte.

ah, ich verstehe, macht Sinn

@justinas Am Ende

from invoke import run as local

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

Dies ist eine Facette von # 1752 - die Absicht ist, dass sich local wie Invoke verhält und die Umgebung beibehält, und dass sich run wie SSH verhält und die Umgebung verwirft. Im Moment sind die Konfigurationen, die dieses Verhalten steuern, jedoch nicht richtig aufgeteilt - es ist praktisch ein Fehler. Wir werden es bald reparieren.

Danke für die Antwort!

Ich bin gerade auf dasselbe Problem gestoßen und wollte nur darauf hinweisen, dass nicht nur die lokale Umgebung verworfen wird.

Vielleicht kennen Sie diesen Fehler auch schon.

Zur Verdeutlichung hat das bei mir nicht funktioniert:

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

Vorerst habe ich diese Problemumgehung (nicht sehr sauber) gefunden, die ich verwenden kann:

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

Ja, das ist dir bewusst, danke!

Sie können run('...', preserve_env=True) sagen, um das jetzt zu umgehen, IIRC.

preserve_env scheint nicht zu existieren. Vielleicht haben Sie sich auf replace_env=False ?
Das löst keinen Fehler aus, aber die Umgebung wird immer noch verworfen.

PS: Ich muss die Umgebung für Remote-Aufgaben einstellen, nicht für lokale.

Ja, ich meinte replace_env und es ist komisch, dass das nicht funktioniert. Ich werde einen Blick darauf werfen, wenn ich die Konfiguration zwischen lokal / remote aufteilen kann (# 1752).

Ich bin auch nur darauf gestoßen. Ich habe c.run('make build') und keiner meiner ENV hat es geschafft (speziell GOPATH, was dazu führte, dass der Build fehlschlug). Das Hinzufügen von replace_env=False Problem behoben.

Bearbeiten: Ich sehe nach den Dokumenten :

run.replace_env: True anstelle von False, sodass Remotebefehle mit einer 'sauberen', leeren Umgebung ausgeführt werden, anstatt eine Kopie der aktuellen Prozessumgebung zu erben.

Es war nur ein bisschen verwirrend für mich, da ich versuchte, einen lokalen Befehl auszuführen.

Das Problem ist immer noch vorhanden, wenn der lokale Befehl ausgeführt wird. @bitprophet

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen