Fabric: Gestion des entrées étrange sous Windows dans Fab2

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

Le tissu 1 gère correctement la saisie manuelle, mais le tissu 2 se comporte étrangement, avec pty ou sans.

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>

Testé sur Windows 7 64b en cmd, Python 3.7 64b, avec les versions Fabric:
Fabric3 1.14.post1, Fabric 2.3.1, Paramiko 2.4.1, Invoke 1.1.1

Bug Needs investigation Nonstandard platforms

Commentaire le plus utile

Voici un changement radical de l'invoke de la version 1.2 à la version 1.3.
https://github.com/pyinvoke/invoke/issues/654

Tous les 11 commentaires

Merci pour le rapport. Je ne suis pas en mesure d'effectuer moi-même le diagnostic sur les systèmes Windows, mais j'espère que quelqu'un d'autre pourra peut-être reproduire. Je peux dire que nous avons définitivement éliminé un certain nombre de problèmes liés aux terminaux et à l'encodage liés à Windows dans le passé afin que les choses _devraient_ être assez stables là-bas, mais vous en avez peut-être trouvé un autre.

Une autre question déclenchée par un autre ticket - est-ce que cela s'est toujours produit ou n'a-t-il commencé que récemment? Un autre utilisateur a signalé un comportement étrange (mais différent de ce symptôme signalé) après une récente mise à jour de Windows.

Je ne peux pas dire s'il a commencé récemment ou non, car je ne l'ai pas testé auparavant.
Maintenant, je l'ai essayé sur Windows 10 en Python 3.5.3 et aucun changement.
Je l'ai essayé plusieurs fois et une fois qu'il s'est retrouvé sur cette erreur:

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

Salut,

Tout correctif à ce sujet. Nous avons le même problème que celui indiqué ci-dessus.

2019-08-07 11: 31: 30,590 - vm-1.0-GA-x86_64-minimal-template-1.0-Update-917-1565202528 - INFO - exec [cd / root || exit $ ?; mkdir -m 777 -p / mnt / shared-1565202528]
testlist: {'tests': [{'test_catagory': 'upgrade', 'test_json': 'runlists / upgrade.json', 'priority': 'P0'}]}
Traceback (dernier appel le plus récent):
Fichier "harnais.py", ligne 395, dans
principale()
Fichier "harnais.py", ligne 392, dans main
sys.exit (harnais.start_run ())
Fichier "harnais.py", ligne 59, dans start_run
result_map = self.run ()
Fichier "harnais.py", ligne 84, en cours d'exécution
result_map [test ['test_catagory']] = self.run_tests (test)
Fichier "harnais.py", ligne 127, dans run_tests
self.mount_storage_on_vm (vm_object)
Fichier "harnais.py", ligne 241, dans mount_storage_on_vm
"mkdir -m 777 -p% s"% (self.log_location)). return_code == 0:
Fichier "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/guest.py", ligne 36, dans run_with_cd
return conn.run ("cd {} || exit $ ?; {}". format (quote (dir), commande), * args)Fichier "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/vm.py", ligne 242, dans _pre_runreturn _orig_run (commande, * kwargs)
Déposer "", ligne 2, en cours
Le fichier "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", ligne 30, s'ouvre
méthode de retour (self, args, * kwargs)
Fichier "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", ligne 702, en cours d'exécution
retourne self._run (self._remote_runner (), commande, * kwargs)Fichier "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/context.py", ligne 101, dans _runretourne runner.run (commande, * kwargs)
Fichier "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", ligne 291, en cours d'exécution
retourne self._run_body (commande, ** kwargs)
Fichier "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", ligne 399, dans _run_body
lever ThreadException (thread_exceptions)
invoke.exceptions.ThreadException:
A vu 1 exceptions dans les threads (NotImplementedError):

Arguments du fil de discussion: {'kwargs': {'echo': Aucun,
'input_': <_io.textiowrapper i = "44">,
'sortie': <_io.textiowrapper i = "46">},
'cible':>}

Traceback (dernier appel le plus récent):

Fichier "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/util.py", ligne 233, en cours d'exécution
super (ExceptionHandlingThread, self) .run ()

Fichier "/usr/lib/python3.6/threading.py", ligne 864, en cours d'exécution
self._target ( self._args, * self._kwargs)

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

Fichier "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", ligne 939, dans close_proc_stdin
lever NotImplementedError

NotImplementedError

Le même problème s'est produit le 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

Je pourrais obtenir le nom d'hôte de stdout. Mais j'ai toujours l'exception comme ci-dessous.

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

Mon contenu de requirements.txt comme ci-dessous:

requests==2.11.1
fabric==2.4.0
xmltodict

J'ai constaté que j'installerais différentes versions de packages après avoir exécuté pip install -r requirements.txt depuis le 07/08/2019.

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 version du package invoke est différente.

Voici un changement radical de l'invoke de la version 1.2 à la version 1.3.
https://github.com/pyinvoke/invoke/issues/654

super trouvaille @baconYao , cela me bloquait aussi. rétrograder invoke pour l'instant à 1.2 m'a permis de surmonter ce problème. Très appréciée.

Idem ici, à chaque pression de touche dans une tâche filetée en cours d'exécution, j'obtiens une erreur 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

J'ai eu le même problème avec 2.4.0. J'utilisais fab dans une tâche de céleri. Pour une raison quelconque, la mise à niveau vers la version 2.5.0 l'a résolu.

Ce problème peut également être lié aux environnements Windows ou WSL. Nous avons eu le même stacktrace en utilisant le dernier Ubuntu WSL sur le dernier Windows 10 et l'avons résolu en exécutant nos tâches sur macOS.
Mettre à niveau ou rétrograder le fabric et / ou invoquer comme mentionné ci-dessus n'a pas fonctionné pour nous.

La chose étrange est que la plupart des tâches fonctionnaient également sur WSL, seule une tâche très longue (de nombreuses commandes run ()) a échoué avec cette exception de manière non déterministe, c'est-à-dire après un certain nombre incertain de commandes exécutées.

Je suis tellement contente d'avoir pu trouver ça.

Lors d'une enquête plus approfondie, il pourrait également être connecté à la classe Responder. Nous avons utilisé un répondeur pour répondre "oui" sur quelques commandes .run () consécutives rapides, et cela échouait sur WSL. La suppression des objets Responder et l'appel de "yes | the-command" fonctionnaient également sur WSL.

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