Fabric: Seltsame Eingabebehandlung unter Windows in Fab2

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

Fabric 1 verarbeitet die manuelle Eingabe korrekt, aber Fabric 2 verhält sich seltsam, mit oder ohne Pty.

Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.

# contents of test_input.sh
# #!/bin/bash
# read -p "enter value: " var
# echo "you entered $var"

# Fabric 1 handled input correctly
>>> run("~/test_input.sh")
[riskapp.comm.equabank.loc] run: ~/test_input.sh
[riskapp.comm.equabank.loc] Login password for 'user':
[riskapp.comm.equabank.loc] out: enter value: foo # typed "foo" ENTER
[riskapp.comm.equabank.loc] out: you entered foo
[riskapp.comm.equabank.loc] out:

'enter value: foo\r\nyou entered foo'

# Fabric 2 without pty doesn't show prompt and behaves strange, must hit enter twice to finish command
>>> c = Connection(SERVER, connect_kwargs={"password": PASSWORD})
>>> c.run("~/test_input.sh")
bar # typed "bar" ENTER
bar # only "b" appeared, the rest after another ENTER


you entered bar
<Result cmd='~/test_input.sh' exited=0>

# Fabric 2 with pty shows prompt but input behavior is still strange, still must hit enter twice
>>> c.run("~/test_input.sh", pty=True)
enter value: baz  # typed "baz" ENTER
b  # another ENTER
az

you entered baz
<Result cmd='~/test_input.sh' exited=0>

# Fabric 2 automatic response works ok with pty
>>> c.run("~/test_input.sh", pty=True, watchers=[Responder(pattern="enter value", response="foo\n")])
enter value: foo
you entered foo
<Result cmd='~/test_input.sh' exited=0>

Getestet unter Windows 7 64b in cmd, Python 3.7 64b, mit Fabric-Versionen:
Fabric3 1.14.post1, Fabric 2.3.1, Paramiko 2.4.1, Invoke 1.1.1

Bug Needs investigation Nonstandard platforms

Hilfreichster Kommentar

Hier ist eine bahnbrechende Änderung des Aufrufs von 1.2 auf 1.3.
https://github.com/pyinvoke/invoke/issues/654

Alle 11 Kommentare

Danke für den Bericht. Ich kann auf Windows-Systemen selbst keine Diagnose durchführen, aber hoffentlich kann jemand anderes die Daten reproduzieren. Ich kann sagen, dass wir in der Vergangenheit definitiv eine Reihe von Problemen im Zusammenhang mit Terminals und Codierung im Zusammenhang mit Windows beseitigt haben, sodass die Dinge dort ziemlich stabil sein sollten, aber Sie haben vielleicht ein anderes gefunden.

Eine andere Frage, die durch ein anderes Ticket ausgelöst wurde - ist dies immer passiert oder hat es erst vor kurzem begonnen? Ein anderer Benutzer hat nach einem kürzlich durchgeführten Windows-Update ein seltsames Verhalten gemeldet (das sich jedoch von diesem gemeldeten Symptom unterscheidet).

Ich kann nicht sagen, ob es vor kurzem angefangen hat oder nicht, weil ich es noch nicht getestet habe.
Jetzt habe ich es unter Windows 10 in Python 3.5.3 versucht und keine Änderung.
Ich habe es mehrmals versucht und als es auf diesen Fehler kam:

>>> c.run("~/test_input.sh")
asv  # i typed "asv" ENTER
asv  # another ENTER
you entered asv

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<decorator-gen-3>", line 2, in run
  File "C:\Python35\lib\site-packages\fabric2\connection.py", line 30, in opens
    return method(self, *args, **kwargs)
  File "C:\Python35\lib\site-packages\fabric2\connection.py", line 702, in run
    return self._run(self._remote_runner(), command, **kwargs)
  File "C:\Python35\lib\site-packages\invoke\context.py", line 101, in _run
    return runner.run(command, **kwargs)
  File "C:\Python35\lib\site-packages\invoke\runners.py", line 271, in run
    return self._run_body(command, **kwargs)
  File "C:\Python35\lib\site-packages\invoke\runners.py", line 365, in _run_body
    raise ThreadException(thread_exceptions)
invoke.exceptions.ThreadException:
Saw 1 exceptions within threads (OSError):

Thread args: {'kwargs': {'echo': None,
            'input_': <_io.TextIOWrapper name='<stdin>' mode='r' encoding='cp852'>,
            'output': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='cp852'>},
 'target': <bound method Runner.handle_stdin of <fabric2.runners.Remote object at 0x000001BF0189C908>>}

Traceback (most recent call last):
  File "C:\Python35\lib\site-packages\invoke\util.py", line 233, in run
    super(ExceptionHandlingThread, self).run()
  File "C:\Python35\lib\threading.py", line 862, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Python35\lib\site-packages\invoke\runners.py", line 648, in handle_stdin
    self.write_proc_stdin(data)
  File "C:\Python35\lib\site-packages\invoke\runners.py", line 784, in write_proc_stdin
    self._write_proc_stdin(data.encode(self.encoding))
  File "C:\Python35\lib\site-packages\fabric2\runners.py", line 69, in _write_proc_stdin
    return self.channel.sendall(data)
  File "C:\Python35\lib\site-packages\paramiko\channel.py", line 846, in sendall
    sent = self.send(s)
  File "C:\Python35\lib\site-packages\paramiko\channel.py", line 801, in send
    return self._send(s, m)
  File "C:\Python35\lib\site-packages\paramiko\channel.py", line 1180, in _send
    raise socket.error("Socket is closed")

OSError: Socket is closed

Hallo,

Irgendwelche Korrekturen. Wir haben das gleiche Problem wie oben gezeigt.

2019-08-07 11: 31: 30,590 - vm-1.0-GA-x86_64-minimal-template-1.0-Update-917-1565202528 - INFO - exec [cd / root || Ausfahrt $?; mkdir -m 777 -p / mnt / shared-1565202528]
Testliste: {'tests': [{'test_catagory': 'upgrade', 'test_json': 'runlists / upgrade.json', 'priority': 'P0'}]}
Traceback (letzter Anruf zuletzt):
Datei "nutzt.py", Zeile 395, in
Main()
Datei "nutzt.py", Zeile 392, in main
sys.exit (nutzt.start_run ())
Datei "nutzt.py", Zeile 59, in start_run
result_map = self.run ()
Datei "nutzt.py", Zeile 84, im Lauf
result_map [test ['test_catagory']] = self.run_tests (test)
Datei "nutzt.py", Zeile 127, in run_tests
self.mount_storage_on_vm (vm_object)
Datei "nutzt.py", Zeile 241, in mount_storage_on_vm
"mkdir -m 777 -p% s"% (self.log_location)). return_code == 0:
Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/guest.py", Zeile 36, in run_with_cd
return conn.run ("cd {} || exit $?; {}". format (quote (dir), command), * args)Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/vm.py", Zeile 242, in _pre_runreturn _orig_run (Befehl, * kwargs)
Datei "", Zeile 2, im Lauf
Die Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", Zeile 30, wird geöffnet
Rückgabemethode (self, args, * kwargs)
Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", Zeile 702, wird ausgeführt
return self._run (self._remote_runner (), Befehl, * kwargs)Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/context.py", Zeile 101, in _runreturn running.run (Befehl, * kwargs)
Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", Zeile 291, wird ausgeführt
return self._run_body (Befehl, ** kwargs)
Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", Zeile 399, in _run_body
ThreadException auslösen (thread_exceptions)
invoke.exceptions.ThreadException:
Sah 1 Ausnahmen innerhalb von Threads (NotImplementedError):

Thread-Argumente: {'kwargs': {'echo': Keine,
'input_': <_io.textiowrapper i = "44">,
'Ausgabe': <_io.textiowrapper i = "46">},
'Ziel':>}

Traceback (letzter Anruf zuletzt):

Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/util.py", Zeile 233, wird ausgeführt
super (ExceptionHandlingThread, self) .run ()

Datei "/usr/lib/python3.6/threading.py", Zeile 864, wird ausgeführt
self._target ( self._args, * self._kwargs)

Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", Zeile 706, in handle_stdin
self.close_proc_stdin ()

Datei "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", Zeile 939, in close_proc_stdin
NotImplementedError auslösen

NotImplementedError

Das gleiche Problem trat am 07.08.2019 auf

def ssh_login_target_nas():
    """ Use ssh to login the target NAS 

        return 
            type: <class 'fabric.connection.Connection'>
    """
    # Set up fabric's login information
    host = SSH_ACCOUNT + "@" + SELF_NAS_IP_ADDRESS              
    # Connect to your nas
    c = Connection(host = host, connect_kwargs={"password": SSH_ACCOUNT_PASSWORD})
    try:
        hostname = c.run('hostname').stdout.strip()
        logger.debug("Connect to NAS: " + hostname)
    except Exception, error:
        logger.error(error)
        raise SystemExit
    return c

Ich könnte den Hostnamen von stdout bekommen. Aber ich habe immer noch die Ausnahme wie unten.

05:57:13 [ERROR] - 2019-08-08 05:58:17,108 - auto_update: ssh_login_target_nas 54   - 
05:57:13 Saw 1 exceptions within threads (NotImplementedError):
05:57:13 
05:57:13 
05:57:13 Thread args: {'kwargs': {'echo': None,
05:57:13             'input_': <open file '<stdin>', mode 'r' at 0x7fbf8f39b0c0>,
05:57:13             'output': <open file '<stdout>', mode 'w' at 0x7fbf8f39b150>},
05:57:13  'target': <bound method Remote.handle_stdin of <fabric.runners.Remote object at 0x7fbf8c6d3e10>>}
05:57:13 
05:57:13 Traceback (most recent call last):
05:57:13 
05:57:13   File "/home/vagrant/workspace/qsirch-v4.1-ui-autotester-chrome/qpkg-update/uenv/local/lib/python2.7/site-packages/invoke/util.py", line 233, in run
05:57:13     super(ExceptionHandlingThread, self).run()
05:57:13 
05:57:13   File "/usr/lib/python2.7/threading.py", line 754, in run
05:57:13     self.__target(*self.__args, **self.__kwargs)
05:57:13 
05:57:13   File "/home/vagrant/workspace/qsirch-v4.1-ui-autotester-chrome/qpkg-update/uenv/local/lib/python2.7/site-packages/invoke/runners.py", line 706, in handle_stdin
05:57:13     self.close_proc_stdin()
05:57:13 
05:57:13   File "/home/vagrant/workspace/qsirch-v4.1-ui-autotester-chrome/qpkg-update/uenv/local/lib/python2.7/site-packages/invoke/runners.py", line 939, in close_proc_stdin
05:57:13     raise NotImplementedError
05:57:13 
05:57:13 NotImplementedError

Mein Inhalt der Anforderungen.txt wie folgt:

requests==2.11.1
fabric==2.4.0
xmltodict

Ich habe festgestellt, dass ich nach der Ausführung von pip install -r requirements.txt seit dem 07.08.2019 eine andere Version von Paketen installieren würde.

06.08.2019.

Successfully installed asn1crypto-0.24.0 bcrypt-3.1.7 cffi-1.12.3 cryptography-2.7 enum34-1.1.6 fabric-2.4.0 invoke-1.2.0 ipaddress-1.0.22 paramiko-2.6.0 pycparser-2.19 pynacl-1.3.0 requests-2.11.1 six-1.12.0 xmltodict-0.12.0

07.08.2019.

Successfully installed asn1crypto-0.24.0 bcrypt-3.1.7 cffi-1.12.3 cryptography-2.7 enum34-1.1.6 fabric-2.4.0 invoke-1.3.0 ipaddress-1.0.22 paramiko-2.6.0 pycparser-2.19 pynacl-1.3.0 requests-2.11.1 six-1.12.0 xmltodict-0.12.0

Die Version des Aufrufpakets ist unterschiedlich.

Hier ist eine bahnbrechende Änderung des Aufrufs von 1.2 auf 1.3.
https://github.com/pyinvoke/invoke/issues/654

toller Fund @baconYao , das hat mich auch blockiert. Das Herabstufen von invoke auf 1.2 hat mich an diesem Problem vorbei gebracht. Sehr geschätzt.

Gleich hier erhalte ich bei jedem Tastendruck in einer kontinuierlich laufenden Thread-Aufgabe einen Socket-Fehler.

Saw 1 exceptions within threads (OSError):

Thread args: {'kwargs': {'echo': None,
            'input_': <_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>,
            'output': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>},
 'target': <bound method Runner.handle_stdin of <fabric.runners.Remote object at 0x7fcad97aeed0>>}

Traceback (most recent call last):

  File "/home/ds/.local/share/virtualenvs/port_error_histogram-BRcAd8l-/lib/python3.7/site-packages/invoke/util.py", line 233, in run
    super(ExceptionHandlingThread, self).run()

  File "/usr/lib64/python3.7/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)

  File "/home/ds/.local/share/virtualenvs/port_error_histogram-BRcAd8l-/lib/python3.7/site-packages/invoke/runners.py", line 694, in handle_stdin
    self.write_proc_stdin(data)

  File "/home/ds/.local/share/virtualenvs/port_error_histogram-BRcAd8l-/lib/python3.7/site-packages/invoke/runners.py", line 832, in write_proc_stdin
    self._write_proc_stdin(data.encode(self.encoding))

  File "/home/ds/.local/share/virtualenvs/port_error_histogram-BRcAd8l-/lib/python3.7/site-packages/fabric/runners.py", line 67, in _write_proc_stdin
    return self.channel.sendall(data)

  File "/home/ds/.local/share/virtualenvs/port_error_histogram-BRcAd8l-/lib/python3.7/site-packages/paramiko/channel.py", line 846, in sendall
    sent = self.send(s)

  File "/home/ds/.local/share/virtualenvs/port_error_histogram-BRcAd8l-/lib/python3.7/site-packages/paramiko/channel.py", line 801, in send
    return self._send(s, m)

  File "/home/ds/.local/share/virtualenvs/port_error_histogram-BRcAd8l-/lib/python3.7/site-packages/paramiko/channel.py", line 1198, in _send
    raise socket.error("Socket is closed")

OSError: Socket is closed

Ich hatte das gleiche Problem mit 2.4.0. Ich habe Fab in einer Sellerie-Aufgabe verwendet. Aus irgendeinem Grund wurde das Upgrade auf 2.5.0 behoben.

Dieses Problem kann auch mit Windows- oder WSL-Umgebungen verbunden sein. Wir hatten den gleichen Stacktrace mit der neuesten Ubuntu WSL unter Windows 10 und haben ihn gelöst, indem wir unsere Aufgaben unter macOS ausgeführt haben.
Das Aufrüsten oder Herabstufen von Fabric und / oder Aufrufen wie oben erwähnt hat bei uns nicht funktioniert.

Das Seltsame ist, dass die meisten Aufgaben auch in der WSL funktionierten. Nur eine sehr lange Aufgabe (viele run () - Befehle) schlug mit dieser Ausnahme nicht deterministisch fehl, dh nachdem eine ungewisse Anzahl von Befehlen ausgeführt wurde.

Ich bin so froh, dass ich das finden konnte.

Bei weiteren Untersuchungen könnte es auch mit der Responder-Klasse verbunden werden. Wir haben einen Responder verwendet, um bei einigen schnellen aufeinanderfolgenden .run () - Befehlen mit "Ja" zu antworten. Dies würde bei der WSL fehlschlagen. Das Entfernen der Responder-Objekte und das Aufrufen von "yes | the-command" funktionierte stattdessen auch für die WSL.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen