Fabric: Fab2在Windows上进行奇怪的输入处理

创建于 2018-09-14  ·  11评论  ·  资料来源: fabric/fabric

Fabric 1正确处理了手动输入,但无论是否带有pty,Fabric 2的行为都异常。

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>

已在Windows 7 64b cmd,Python 3.7 64b和Fabric版本中进行了测试:
Fabric3 1.14.post1,Fabric 2.3.1,Paramiko 2.4.1,调用1.1.1

Bug Needs investigation Nonstandard platforms

最有用的评论

这是从1.2版本到1.3版本的调用的重大变化。
https://github.com/pyinvoke/invoke/issues/654

所有11条评论

感谢您的报告。 我自己无法在Windows系统上执行诊断,但希望其他人也可以复制。 我可以说我们过去肯定已经解决了许多与Windows有关的与终端和编码有关的问题,因此,那里的情况应该很稳定,但是您可能已经发现了另一个问题。

由另一张票证触发的另一个问题-是总是发生这种情况还是只是最近才开始? 另一个用户在最近的Windows更新之后报告了一些奇怪的行为(但不同于此报告的症状)。

我不能说它是否最近才开始,因为我以前没有测试过。
现在,我在Windows 10上的Python 3.5.3中进行了尝试,并且没有任何更改。
我尝试了几次,一旦出现此错误,它就结束了:

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

你好,

任何修复。 我们有与上述相同的问题。

2019-08-07 11:31:30,590-vm-1.0-GA-x86_64-minimal-template-1.0-Update-917-1565202528-信息-exec [cd / root || 退出$ ?; mkdir -m 777 -p / mnt / shared-1565202528]
测试列表:{'tests':[{'test_catagory':'upgrade','test_json':'runlists / upgrade.json','priority':'P0'}]}
追溯(最近一次通话):
在第395行的文件“ harness.py”中
主要的()
主文件“ harness.py”,第392行
sys.exit(harness.start_run())
在start_run中,文件“ harness.py”,第59行
result_map = self.run()
运行中的文件“ harness.py”,第84行
result_map [test ['test_catagory']] = self.run_tests(test)
在run_tests中的文件“ harness.py”,第127行
self.mount_storage_on_vm(vm_object)
mount_storage_on_vm中的文件“ harness.py”,第241行
“ mkdir -m 777 -p%s”%(self.log_location))。return_code == 0:
文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/guest.py”,第36行,在run_with_cd中
return conn.run(“ cd {} || exit $ ?; {}”。format(quote(dir),command), * args)文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/vm.py”,第242行,在_pre_run中return _orig_run(command,* kwargs)
文件 ””,第2行
打开文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py”,第30行
返回方法(self, args,* kwargs)
运行中的文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py”,第702行
返回self._run(self._remote_runner(),命令, * kwargs)文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/context.py”,第101行,在_run中返回runner.run(命令,* kwargs)
运行中的文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py”,第291行
返回self._run_body(command,** kwargs)
文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py”,行399,在_run_body中
引发ThreadException(thread_exceptions)
invoke.exceptions.ThreadException:
在线程中看到1个异常(NotImplementedError):

线程参数:{'kwargs':{'echo':无,
'input_':<_io.textiowrapper i =“ 44”>,
'输出':<_ io.textiowrapper i =“ 46”>},
'目标':>}

追溯(最近一次通话):

正在运行的文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/util.py”,第233行
超级(ExceptionHandlingThread,self).run()

运行中的文件“ /usr/lib/python3.6/threading.py”,行864
self._target( self._args,* self._kwargs)

文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py”,行706,位于handle_stdin中
self.close_proc_stdin()

文件“ /root/workspace/upgrade-test-CI-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py”,行939,在close_proc_stdin中
引发NotImplementedError

NotImplementedError

同样的问题发生在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

我可以从stdout获取主机名。 但是我仍然遇到如下异常。

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

我的requirements.txt内容如下:

requests==2.11.1
fabric==2.4.0
xmltodict

我发现自2019/08/07起执行pip install -r requirements.txt后将安装不同版本的软件包。

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

invoke软件包的版本不同。

这是从1.2版本到1.3版本的调用的重大变化。
https://github.com/pyinvoke/invoke/issues/654

很棒的发现@baconYao ,这也阻止了我。 现在将调用降级到1.2已使我克服了这个问题。 非常感激。

同样,在连续运行线程任务的任何按键上,我都收到套接字错误。

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

我在2.4.0中有同样的问题。 我在芹菜任务中使用fab。 出于某种原因,升级到2.5.0可以解决该问题。

此问题也可能连接到Windows或WSL环境。 我们在最新的Windows 10上使用最新的Ubuntu WSL具有相同的stacktrace,并通过在macOS上运行任务来解决了该问题。
如上所述,升级或降级结构和/或调用对我们不起作用。

奇怪的是,大多数任务也可以在WSL上运行,只有一个很长的任务(许多run()命令)确实不确定地失败,但有一些不确定的命令运行。

我很高兴能够找到这个。

在进一步调查中,它也可以连接到“响应者”类。 我们使用响应器在几个快速连续的.run()命令上回答“是”,而这在WSL上将失败。 删除Responder对象并调用“ yes | the-command”也可以在WSL上使用。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

harobed picture harobed  ·  5评论

acdha picture acdha  ·  4评论

bitprophet picture bitprophet  ·  4评论

SamuelMarks picture SamuelMarks  ·  3评论

peteruhnak picture peteruhnak  ·  4评论