Fabric: Manipulação de entrada estranha no Windows em Fab2

Criado em 14 set. 2018  ·  11Comentários  ·  Fonte: fabric/fabric

O Tecido 1 lida com a entrada manual corretamente, mas o Tecido 2 se comporta de maneira estranha, com ou sem 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>

Testado em Windows 7 64b em cmd, Python 3.7 64b, com versões Fabric:
Fabric3 1.14.post1, Fabric 2.3.1, Paramiko 2.4.1, Invoke 1.1.1

Bug Needs investigation Nonstandard platforms

Comentários muito úteis

Aqui está uma mudança significativa de invoke de 1.2 para 1.3 verion.
https://github.com/pyinvoke/invoke/issues/654

Todos 11 comentários

Obrigado pelo relatório. Não consigo realizar o diagnóstico em sistemas Windows sozinho, mas espero que outra pessoa consiga reproduzir. Posso dizer que definitivamente eliminamos uma série de problemas relacionados ao terminal e codificação relacionados ao Windows no passado, então as coisas _devem_ estar bem estáveis ​​lá, mas você pode ter encontrado outro.

Outra pergunta desencadeada por outro tíquete - isso sempre aconteceu ou só começou recentemente? Outro usuário relatou algum comportamento estranho (mas diferente do sintoma relatado) após uma atualização recente do Windows.

Não sei dizer se começou recentemente ou não, porque nunca testei antes.
Agora tentei no Windows 10 em Python 3.5.3 e nenhuma alteração.
Tentei várias vezes e, uma vez, resultou neste erro:

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

Oi,

Qualquer correção nisso. Temos o mesmo problema mostrado acima.

07/08/2019 11: 31: 30.590 - vm-1.0-GA-x86_64-minimal-template-1.0-Update-917-1565202528 - INFO - exec [cd / root || sair $ ?; mkdir -m 777 -p / mnt / shared-1565202528]
testlist: {'tests': [{'test_catagory': 'upgrade', 'test_json': 'runlists / upgrade.json', 'priority': 'P0'}]}
Traceback (última chamada mais recente):
Arquivo "harness.py", linha 395, em
a Principal()
Arquivo "harness.py", linha 392, em principal
sys.exit (harness.start_run ())
Arquivo "harness.py", linha 59, em start_run
result_map = self.run ()
Arquivo "harness.py", linha 84, em execução
result_map [test ['test_catagory']] = self.run_tests (teste)
Arquivo "harness.py", linha 127, em run_tests
self.mount_storage_on_vm (vm_object)
Arquivo "harness.py", linha 241, em mount_storage_on_vm
"mkdir -m 777 -p% s"% (self.log_location)). return_code == 0:
Arquivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/guest.py", linha 36, em run_with_cd
return conn.run ("cd {} || exit $ ?; {}". format (quote (dir), command), * args)Arquivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/vm.py", linha 242, em _pre_runreturn _orig_run (command, * kwargs)
Arquivo "", linha 2, em execução
O arquivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", linha 30, abre
método de retorno (self, args, * kwargs)
Arquivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", linha 702, em execução
return self._run (self._remote_runner (), command, * kwargs)Arquivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/context.py", linha 101, em _runreturn runner.run (command, * kwargs)
Arquivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", linha 291, em execução
return self._run_body (comando, ** kwargs)
Arquivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", linha 399, em _run_body
levantar ThreadException (thread_exceptions)
invoke.exceptions.ThreadException:
Viu 1 exceção em threads (NotImplementedError):

Argumentos do tópico: {'kwargs': {'echo': Nenhum,
'input_': <_io.textiowrapper i = "44">,
'output': <_io.textiowrapper i = "46">},
'alvo':>}

Traceback (última chamada mais recente):

Arquivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/util.py", linha 233, em execução
super (ExceptionHandlingThread, self) .run ()

Arquivo "/usr/lib/python3.6/threading.py", linha 864, em execução
self._target ( self._args, * self._kwargs)

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

Arquivo "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", linha 939, em close_proc_stdin
aumentar NotImplementedError

NotImplementedError

O mesmo problema ocorreu em 07/08/2019

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

Eu poderia obter o nome do host de stdout. Mas ainda tenho a exceção como abaixo.

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

Meu conteúdo de requirements.txt como abaixo:

requests==2.11.1
fabric==2.4.0
xmltodict

Descobri que instalaria versões diferentes de pacotes depois de executar pip install -r requirements.txt desde 07/08/2019.

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

A versão do pacote invoke é diferente.

Aqui está uma mudança significativa de invoke de 1.2 para 1.3 verion.
https://github.com/pyinvoke/invoke/issues/654

ótimo achado @baconYao , isso também estava me bloqueando. rebaixar invoke por enquanto para 1.2 me ajudou a superar esse problema. Muito apreciado.

O mesmo aqui, em qualquer pressionamento de tecla em uma tarefa encadeada em execução contínua, recebo um erro de soquete.

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

Eu tive o mesmo problema com 2.4.0. Eu estava usando fab dentro de uma tarefa de aipo. Por alguma razão, atualizar para 2.5.0 resolveu o problema.

Esse problema também pode estar conectado a ambientes Windows ou WSL. Tivemos o mesmo rastreamento de pilha usando o Ubuntu WSL mais recente no último Windows 10 e resolvemos isso executando nossas tarefas no macOS.
Atualizar ou reduzir o tecido e / ou invocar conforme mencionado acima não funcionou para nós.

O estranho é que a maioria das tarefas também funcionava no WSL, apenas uma tarefa muito longa (muitos comandos run ()) falhou com essa exceção de forma não determinística, ou seja, após um número incerto de comandos executados.

Estou tão feliz por ter encontrado isso.

Em uma investigação mais aprofundada, ele também pode ser conectado à classe Responder. Usamos um respondedor para responder "sim" em alguns comandos .run () consecutivos rápidos, e isso falharia no WSL. Remover os objetos Responder e chamar "yes | the-command" em vez disso funcionou no WSL também.

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

acdha picture acdha  ·  4Comentários

shadyabhi picture shadyabhi  ·  5Comentários

bitprophet picture bitprophet  ·  4Comentários

haydenflinner picture haydenflinner  ·  5Comentários

jmcgrath207 picture jmcgrath207  ·  5Comentários