当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”行为模式:如果出现任何错误,例如返回非零返回值的远程程序或者fabfile的Python代码遇到exception,执行将立即停止。

这通常是所需的行为,但是规则有很多例外,所以Fabric提供了一个布尔设置env.warn_only。 它默认为False,这意味着错误情况会导致程序立即中止。 但是,如果env.warn_only在发生故障时设置为True(例如设置上下文pipe理器),Fabric将发出警告消息,但继续执行。

看起来像你可以通过使用settings上下文pipe理器对错误被忽略的地方进行细粒度的控制,如下所示:

 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环境variables并捕获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. 

你也可以在一个块中设置它。 请参阅这里的文档。

在Fabric 1.3.2中,至less可以通过捕获SystemExitexception来恢复exception。 如果您有多个命令在批处理中运行(如部署),并希望在其中一个失败时清除,那么这会很有帮助。

在我的情况下,Fabric> = 1.4 这个答案是正确的。

你可以通过添加这个跳过坏主机:

 env.skip_bad_hosts = True 

或者传递--skip-bad-hosts标志/