Fabric 收到错误时如何继续执行任务

发布于 2024-09-26 13:31:13 字数 836 浏览 3 评论 0原文

当我定义一个任务在多个远程服务器上运行时,如果该任务在一台服务器上运行并因错误退出,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.

When I define a task to run on several remote servers, if the task runs on server one and exits with an error, Fabric will stop and abort the task. But I want to make fabric ignore the error and run the task on the next server. How can I make it do this?

For example:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

梦醒时光 2024-10-03 13:31:13

来自文档

... Fabric 默认采用“快速失败”行为模式:如果出现任何问题,例如远程程序返回非零返回值或 fabfile 的 Python 代码遇到异常,执行将立即停止。

这通常是期望的行为,但该规则有许多例外,因此 Fabric 提供了 env.warn_only,一个布尔设置。它默认为 False,这意味着错误情况将导致程序立即中止。但是,如果在失败时将 env.warn_only 设置为 True(例如使用设置上下文管理器),Fabric 将发出警告消息,但会继续执行。

看起来您可以使用 设置上下文管理器,如下所示:

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

From the docs:

... Fabric defaults to a “fail-fast” behavior pattern: if anything goes wrong, such as a remote program returning a nonzero return value or your fabfile’s Python code encountering an exception, execution will halt immediately.

This is typically the desired behavior, but there are many exceptions to the rule, so Fabric provides env.warn_only, a Boolean setting. It defaults to False, meaning an error condition will result in the program aborting immediately. However, if env.warn_only is set to True at the time of failure – with, say, the settings context manager – Fabric will emit a warning message but continue executing.

Looks like you can exercise fine-grained control over where errors are ignored by using the settings context manager, something like so:

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
短叹 2024-10-03 13:31:13

从 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')

As of Fabric 1.5, there is a ContextManager that makes this easier:

from fabric.api import sudo, warn_only

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

Update: I re-confirmed that this works in ipython using the following code.

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')
半暖夏伤 2024-10-03 13:31:13

您还可以将整个脚本的 warn_only 设置为 true

def local():
    env.warn_only = True

You can also set the entire script's warn_only setting to be true with

def local():
    env.warn_only = True
瀞厅☆埖开 2024-10-03 13:31:13

您应该设置 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 块中。请参阅此处的文档。

You should set the abort_exception environment variable and catch the exception.

For example:

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.

You can also set it in a with block. See the documentation here.

夢归不見 2024-10-03 13:31:13

Fabric 2.x中,您只需使用调用运行 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)

In Fabric 2.x you can just use invoke's run with the warn=True argument. Anyway, invoke is a dependency of Fabric 2.x:

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

From within a task:

from invoke import task

@task
def my_task(c):
    c.run('bad command', warn=True)
梦里的微风 2024-10-03 13:31:13

至少在 Fabric 1.3.2 中,您可以通过捕获 SystemExit 异常来恢复异常。如果您有多个命令要批量运行(例如部署)并且希望在其中一个命令失败时进行清理,那么这会很有帮助。

In Fabric 1.3.2 at least, you can recover the exception by catching the SystemExit exception. That's helpful if you have more than one command to run in a batch (like a deploy) and want to cleanup if one of them fails.

呆头 2024-10-03 13:31:13

就我而言,在 Fabric >= 1.4 这个答案是正确的。

您可以通过添加以下内容来跳过不良主机:

env.skip_bad_hosts = True

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

In my case, on Fabric >= 1.4 this answer was the correct one.

You can skip bad hosts by adding this:

env.skip_bad_hosts = True

Or passing the --skip-bad-hosts flag/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文