Fabric: Fab2의 Windowsμ—μ„œ μ΄μƒν•œ μž…λ ₯ 처리

에 λ§Œλ“  2018λ…„ 09μ›” 14일  Β·  11μ½”λ©˜νŠΈ  Β·  좜처: fabric/fabric

패브릭 1은 μˆ˜λ™ μž…λ ₯을 μ˜¬λ°”λ₯΄κ²Œ μ²˜λ¦¬ν•˜μ§€λ§Œ 패브릭 2λŠ” 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>

Windows 7 64bμ—μ„œ cmd, Python 3.7 64b, Fabric λ²„μ „μ—μ„œ ν…ŒμŠ€νŠΈλ˜μ—ˆμŠ΅λ‹ˆλ‹€.
Fabric3 1.14.post1, Fabric 2.3.1, Paramiko 2.4.1, Invoke 1.1.1

Bug Needs investigation Nonstandard platforms

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ‹€μŒμ€ invokeκ°€ 1.2μ—μ„œ 1.3 λ²„μ „μœΌλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
https://github.com/pyinvoke/invoke/issues/654

λͺ¨λ“  11 λŒ“κΈ€

μ‹ κ³  ν•΄ μ£Όμ…”μ„œ κ°μ‚¬ν•©λ‹ˆλ‹€. Windows μ‹œμŠ€ν…œμ—μ„œ 직접 진단을 μˆ˜ν–‰ ν•  μˆ˜λŠ” μ—†μ§€λ§Œ λ‹€λ₯Έ μ‚¬λžŒμ΄ μž¬ν˜„ ν•  수 있기λ₯Ό λ°”λžλ‹ˆλ‹€. 과거에 Windows와 κ΄€λ ¨λœ μ—¬λŸ¬ 터미널 및 인코딩 κ΄€λ ¨ 문제λ₯Ό ν™•μ‹€νžˆ 처리 ν–ˆμœΌλ―€λ‘œ 상황이 κ½€ μ•ˆμ •μ μ΄μ–΄μ•Όν•˜μ§€λ§Œ λ‹€λ₯Έ 문제λ₯Ό λ°œκ²¬ν–ˆμ„ 수 μžˆμŠ΅λ‹ˆλ‹€.

λ‹€λ₯Έ 티켓에 μ˜ν•΄ 유발 된 또 λ‹€λ₯Έ 질문-항상 λ°œμƒ ν–ˆμŠ΅λ‹ˆκΉŒ μ•„λ‹ˆλ©΄ μ΅œκ·Όμ— μ‹œμž‘ λ˜μ—ˆμŠ΅λ‹ˆκΉŒ? λ‹€λ₯Έ μ‚¬μš©μžκ°€ 졜근 Windows μ—…λ°μ΄νŠΈ ν›„ μ΄μƒν•œ λ™μž‘ (이보고 된 μ¦μƒκ³ΌλŠ” 닀름)μ„λ³΄κ³ ν–ˆμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” 그것이 μ΅œκ·Όμ— μ‹œμž‘λ˜μ—ˆλŠ”μ§€ μ—¬λΆ€λ₯Ό 말할 수 μ—†μŠ΅λ‹ˆλ‹€.
이제 Python 3.5.3의 Windows 10μ—μ„œ μ‹œλ„ν–ˆμ§€λ§Œ λ³€κ²½ 사항이 μ—†μŠ΅λ‹ˆλ‹€.
λ‚˜λŠ” 그것을 μ—¬λŸ¬ 번 μ‹œλ„ν–ˆκ³  일단이 였λ₯˜κ°€ λ°œμƒν•˜λ©΄ :

>>> 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'}]}
μ—­ 좔적 (κ°€μž₯ 졜근 호좜 λ§ˆμ§€λ§‰) :
파일 "harness.py", 395 ν–‰, in
λ³Έκ΄€()
파일 "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-in-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-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/photontools/runner/vm.py", 242 ν–‰, _pre_runμ—μ„œreturn _orig_run (λͺ…λ Ή, * kwargs)
파일 "", 2 ν–‰, μ‹€ν–‰ 쀑
파일 "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", 30 ν–‰, μ—΄λ¦Ό
λ°˜ν™˜ 방법 (self, args, * kwargs)
파일 "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/fabric/connection.py", 702 ν–‰ μ‹€ν–‰ 쀑
return self._run (self._remote_runner (), command, * kwargs)파일 "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/context.py", 101 ν–‰, _runreturn runner.run (λͺ…λ Ή, * kwargs)
파일 "/root/workspace/upgrade-test-CI-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/runners.py", 291 ν–‰, μ‹€ν–‰ 쀑
return self._run_body (λͺ…λ Ή, ** kwargs)
파일 "/root/workspace/upgrade-test-CI-in-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-in-harness/update-basic-in-harness/.venv/lib/python3.6/site-packages/invoke/util.py", 233 ν–‰, μ‹€ν–‰ 쀑
super (ExceptionHandlingThread, self) .run ()

"/usr/lib/python3.6/threading.py"파일, 864 ν–‰ μ‹€ν–‰ 쀑
self._target ( self._args, * self._kwargs)

파일 "/root/workspace/upgrade-test-CI-in-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-in-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 νŒ¨ν‚€μ§€μ˜ 버전이 λ‹€λ¦…λ‹ˆλ‹€.

λ‹€μŒμ€ invokeκ°€ 1.2μ—μ„œ 1.3 λ²„μ „μœΌλ‘œ λ³€κ²½λ˜μ—ˆμŠ΅λ‹ˆλ‹€.
https://github.com/pyinvoke/invoke/issues/654

@baconYaoλ₯Ό μ°Ύμ•„μ„œ , 이것은 λ‚˜λ₯Ό λ§‰κ³ μžˆμ—ˆμŠ΅λ‹ˆλ‹€. μ§€κΈˆ invokeλ₯Ό 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을 μ‚¬μš©ν•˜μ—¬ λ™μΌν•œ μŠ€νƒ 좔적을 μˆ˜ν–‰ν–ˆκ³  macOSμ—μ„œ μž‘μ—…μ„ μ‹€ν–‰ν•˜μ—¬ ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹€.
μœ„μ—μ„œ μ–ΈκΈ‰ ν•œλŒ€λ‘œ 패브릭 μ—…κ·Έλ ˆμ΄λ“œ λ˜λŠ” λ‹€μš΄ κ·Έλ ˆμ΄λ“œ 및 / λ˜λŠ” 호좜이 μž‘λ™ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

μ΄μƒν•œ 점은 λŒ€λΆ€λΆ„μ˜ μž‘μ—…μ΄ WSLμ—μ„œλ„ μž‘λ™ν–ˆμœΌλ©° 맀우 κΈ΄ μž‘μ—… (λ§Žμ€ run () λͺ…λ Ή) 만이 μ˜ˆμ™Έμ™€ ν•¨κ»˜ λΉ„ κ²°μ •μ μœΌλ‘œ μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€. 즉, λΆˆν™•μ‹€ν•œ 수의 λͺ…령이 μ‹€ν–‰ 된 후에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.

이것을 찾을 μˆ˜μžˆμ–΄μ„œ 정말 κΈ°μ©λ‹ˆλ‹€.

μΆ”κ°€ μ‘°μ‚¬μ—μ„œ Responder ν΄λž˜μŠ€μ— μ—°κ²°ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. μ‘λ‹΅μžλ₯Ό μ‚¬μš©ν•˜μ—¬ λΉ λ₯Έ 연속 .run () λͺ…λ Ή λͺ‡ κ°œμ— λŒ€ν•΄ "예"라고 λŒ€λ‹΅ν–ˆλŠ”λ° WSLμ—μ„œλŠ” μ‹€νŒ¨ν•©λ‹ˆλ‹€. μ‘λ‹΅μž 개체λ₯Ό μ œκ±°ν•˜κ³  "yes | the-command"λ₯Ό ν˜ΈμΆœν•˜λŠ” λŒ€μ‹  WSLμ—μ„œλ„ μž‘λ™ν–ˆμŠ΅λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰