Fabric: Manejo de entrada extraño en Windows en Fab2

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

La tela 1 maneja la entrada manual correctamente, pero la tela 2 se comporta de manera extraña, con o sin 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>

Probado en Windows 7 64b en cmd, Python 3.7 64b, con versiones de Fabric:
Fabric3 1.14.post1, Fabric 2.3.1, Paramiko 2.4.1, Invoke 1.1.1

Bug Needs investigation Nonstandard platforms

Comentario más útil

Aquí hay un cambio radical de invocación de la versión 1.2 a la 1.3.
https://github.com/pyinvoke/invoke/issues/654

Todos 11 comentarios

Gracias por el informe. No puedo realizar el diagnóstico en los sistemas Windows por mí mismo, pero espero que alguien más pueda reproducirlo. Puedo decir que definitivamente hemos eliminado una serie de problemas relacionados con el terminal y la codificación relacionados con Windows en el pasado, por lo que las cosas _deberían_ ser bastante estables allí, pero es posible que haya encontrado otro.

Otra pregunta desencadenada por otro ticket: ¿ha sucedido siempre o ha comenzado recientemente? Otro usuario informó un comportamiento extraño (pero diferente a este síntoma informado) después de una actualización reciente de Windows.

No puedo decir si comenzó recientemente o no, porque no lo he probado antes.
Ahora lo probé en Windows 10 en Python 3.5.3 y sin cambios.
Lo probé varias veces y una vez terminó con este error:

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

Hola,

Cualquier solución. Tenemos el mismo problema que se muestra arriba.

2019-08-07 11: 31: 30,590 - vm-1.0-GA-x86_64-minimal-template-1.0-Update-917-1565202528 - INFO - exec [cd / root || salir $ ?; mkdir -m 777 -p / mnt / shared-1565202528]
testlist: {'tests': [{'test_catagory': 'upgrade', 'test_json': 'runlists / upgrade.json', 'priority': 'P0'}]}
Rastreo (llamadas recientes más última):
Archivo "harness.py", línea 395, en
principal()
Archivo "harness.py", línea 392, en la página principal
sys.exit (harness.start_run ())
Archivo "harness.py", línea 59, en start_run
result_map = self.run ()
Archivo "harness.py", línea 84, en ejecución
result_map [prueba ['test_catagory']] = self.run_tests (prueba)
Archivo "harness.py", línea 127, en run_tests
self.mount_storage_on_vm (vm_object)
Archivo "harness.py", línea 241, en mount_storage_on_vm
"mkdir -m 777 -p% s"% (self.log_location)). return_code == 0:
Archivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/guest.py", línea 36, en run_with_cd
return conn.run ("cd {} || salir $ ?; {}". formato (comillas (dir), comando), * args)Archivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/vm.py", línea 242, en _pre_runreturn _orig_run (comando, * kwargs)
Archivo "", línea 2, en ejecución
Archivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", línea 30, en aperturas
método de retorno (self, args, * kwargs)
Archivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", línea 702, en ejecución
return self._run (self._remote_runner (), comando, * kwargs)Archivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/context.py", línea 101, en _runreturn runner.run (comando, * kwargs)
Archivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", línea 291, en ejecución
return self._run_body (comando, ** kwargs)
Archivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", línea 399, en _run_body
subir ThreadException (thread_exceptions)
invoke.exceptions.ThreadException:
Vio 1 excepciones dentro de los hilos (NotImplementedError):

Argumentos del hilo: {'kwargs': {'echo': Ninguno,
'input_': <_io.textiowrapper i = "44">,
'salida': <_io.textiowrapper i = "46">},
'objetivo':>}

Rastreo (llamadas recientes más última):

Archivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/util.py", línea 233, en ejecución
super (ExceptionHandlingThread, self) .run ()

Archivo "/usr/lib/python3.6/threading.py", línea 864, en ejecución
self._target ( self._args, * self._kwargs)

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

Archivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", línea 939, en close_proc_stdin
elevar NotImplementedError

NotImplementedError

El mismo problema ocurrió en 2019/08/07

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

Podría obtener el nombre de host de stdout. Pero todavía tengo la excepción como a continuación.

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

Mi contenido de requirements.txt como a continuación:

requests==2.11.1
fabric==2.4.0
xmltodict

Descubrí que instalaría diferentes versiones de paquetes después de ejecutar pip install -r requirements.txt desde 2019/08/07.

2019/08/06.

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

2019/08/07.

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

La versión del paquete de invocación es diferente.

Aquí hay un cambio radical de invocación de la versión 1.2 a la 1.3.
https://github.com/pyinvoke/invoke/issues/654

gran hallazgo @baconYao , esto también me estaba bloqueando. la degradación de invoke por ahora a 1.2 me ha ayudado a superar este problema. Muy apreciado.

Lo mismo aquí, al presionar cualquier tecla en una tarea enhebrada en ejecución continua, obtengo un error de socket.

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

Tuve el mismo problema con 2.4.0. Estaba usando fabuloso dentro de una tarea de apio. Por alguna razón, la actualización a 2.5.0 lo resolvió.

Este problema también podría estar relacionado con entornos Windows o WSL. Tuvimos el mismo stacktrace usando el último Ubuntu WSL en el último Windows 10, y lo resolvimos ejecutando nuestras tareas en macOS.
Actualizar o degradar el tejido o invocar como se mencionó anteriormente no funcionó para nosotros.

Lo extraño es que la mayoría de las tareas también funcionaron en WSL, solo una tarea muy larga (muchos comandos run ()) fallaron con esta excepción de manera no determinista, es decir, después de ejecutar un número incierto de comandos.

Estoy muy contento de haber podido encontrar esto.

En una investigación más profunda, también podría conectarse a la clase Responder. Usamos un respondedor para responder "sí" en un par de comandos .run () rápidos consecutivos, y esto fallaría en WSL. Eliminar los objetos Responder y llamar a "yes | the-command" en su lugar también funcionó en WSL.

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

Temas relacionados

bitprophet picture bitprophet  ·  4Comentarios

acdha picture acdha  ·  4Comentarios

jamesob picture jamesob  ·  3Comentarios

Grazfather picture Grazfather  ·  4Comentarios

peteruhnak picture peteruhnak  ·  6Comentarios