当我定义要在多个远程服务器上运行的任务时,如果任务在服务器1上运行并退出并出现错误,则Fabric将停止并中止该任务。但是我想让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.
答案 0 :(得分:144)
来自the docs:
... Fabric默认为“fail-fast”行为模式:如果出现任何问题,例如远程程序返回非零返回值或fabfile的Python代码遇到异常,执行将立即停止。
这通常是所需的行为,但规则有很多例外,因此Fabric提供了env.warn_only,一个布尔设置。它默认为False,这意味着错误条件将导致程序立即中止。但是,如果在失败时将env.warn_only设置为True - 例如设置上下文管理器 - Fabric将发出警告消息但仍继续执行。
看起来您可以使用settings
context manager对错误被忽略的位置进行细粒度控制,如下所示:
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
答案 1 :(得分:30)
从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')
答案 2 :(得分:13)
您还可以使用
将整个脚本的warn_only设置设置为truedef local():
env.warn_only = True
答案 3 :(得分:10)
您应该设置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块中进行设置。请参阅文档here。
答案 4 :(得分:7)
至少在Fabric 1.3.2中,您可以通过捕获SystemExit
异常来恢复异常。如果您有多个命令在批处理中运行(如部署),并且想要在其中一个命令失败时进行清理,那么这将非常有用。
答案 5 :(得分:6)
在 Fabric 2.x 中,您可以将 invoke 的 run 与 warn = True 参数。无论如何,调用是 Fabric 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)
答案 6 :(得分:-4)
就我而言,在Fabric> = 1.4 this answer上是正确的。
您可以通过添加以下内容来跳过坏主机:
env.skip_bad_hosts = True
或传递--skip-bad-hosts
标志/