[python] Fabric이 오류를 수신 할 때 작업을 계속하는 방법

여러 원격 서버에서 실행할 작업을 정의 할 때 작업이 서버 1에서 실행되고 오류와 함께 종료되면 Fabric은 작업을 중지하고 중단합니다. 하지만 패브릭이 오류를 무시하고 다음 서버에서 작업을 실행하도록 만들고 싶습니다. 어떻게 할 수 있습니까?

예를 들면 :

$ fab site1_service_gw
[site1rpt1] Executing task 'site1_service_gw'

[site1fep1] run: echo 'Nm123!@#' | sudo -S route
[site1fep1] err:
[site1fep1] err: We trust you have received the usual lecture from the local System
[site1fep1] err: Administrator. It usually boils down to these three things:
[site1fep1] err:
[site1fep1] err:     #1) Respect the privacy of others.
[site1fep1] err:     #2) Think before you type.
[site1fep1] err:     #3) With great power comes great responsibility.
[site1fep1] err: root's password:
[site1fep1] err: sudo: route: command not found

Fatal error: run() encountered an error (return code 1) while executing 'echo 'Nm123!@#' | sudo -S route '

Aborting.



답변

에서 워드 프로세서 :

… Fabric은 기본적으로 “fail-fast”동작 패턴을 사용합니다. 원격 프로그램이 0이 아닌 반환 값을 반환하거나 fabfile의 Python 코드에서 예외가 발생하는 등 문제가 발생하면 실행이 즉시 중지됩니다.

이것은 일반적으로 바람직한 동작이지만 규칙에 대한 많은 예외가 있으므로 Fabric은 부울 설정 인 env.warn_only를 제공합니다. 기본값은 False로, 오류 조건이 발생하면 프로그램이 즉시 중단됩니다. 그러나 env.warn_only가 실패시 True로 설정되면 (예 : 설정 컨텍스트 관리자) Fabric은 경고 메시지를 내보내지만 계속 실행합니다.

다음과 같이 settings컨텍스트 관리자 를 사용하여 오류가 무시되는 위치를 세밀하게 제어 할 수있는 것 같습니다.

from fabric.api import settings

sudo('mkdir tmp') # can't fail
with settings(warn_only=True):
    sudo('touch tmp/test') # can fail
sudo('rm tmp') # can't fail


답변

Fabric 1.5부터는 이것을 더 쉽게 만들어주는 ContextManager가 있습니다 :

from fabric.api import sudo, warn_only

with warn_only():
    sudo('mkdir foo')

업데이트 : 다음 코드를 사용하여 ipython에서 작동하는지 다시 확인했습니다.

from fabric.api import local, warn_only

#aborted with SystemExit after 'bad command'
local('bad command'); local('bad command 2')

#executes both commands, printing errors for each
with warn_only():
    local('bad command'); local('bad command 2')


답변

또한 전체 스크립트의 warn_only 설정을 true로 설정할 수도 있습니다.

def local():
    env.warn_only = True


답변

abort_exception환경 변수를 설정 하고 예외를 포착해야합니다.

예를 들면 :

from fabric.api        import env
from fabric.operations import sudo

class FabricException(Exception):
    pass

env.abort_exception = FabricException
# ... set up the rest of the environment...

try:
    sudo('reboot')
except FabricException:
    pass  # This is expected, we can continue.

with 블록에서 설정할 수도 있습니다. 여기 에서 설명서를 참조 하십시오 .


답변

Fabric 1.3.2 이상에서는 예외를 포착하여 SystemExit예외를 복구 할 수 있습니다 . 이는 배치 (예 : 배포)에서 실행할 명령이 두 개 이상 있고 그중 하나가 실패 할 경우 정리하려는 경우 유용합니다.


답변

Fabric 2.x 에서는 warn = True 인수 와 함께 invoke실행 을 사용할 수 있습니다 . 어쨌든 invokeFabric 2.x 의 종속성입니다 .

from invoke import run
run('bad command', warn=True)

작업 내에서 :

from invoke import task

@task
def my_task(c):
    c.run('bad command', warn=True)


답변

제 경우에는 Fabric> = 1.4 에서이 답변 이었습니다.

다음을 추가하여 잘못된 호스트를 건너 뛸 수 있습니다.

env.skip_bad_hosts = True

또는 --skip-bad-hosts깃발 전달 /