Nornir文檔翻譯----第四節(jié) 失敗的任務(wù)

Failed Tasks

有些時候一些任務(wù)會失敗。讓我們看下在nornir中如何處理這些失敗的任務(wù)。
讓我們和之前一樣從樣本代碼開始:

import logging

from nornir import InitNornir
from nornir.core.task import Task, Result
from nornir_utils.plugins.functions import print_result

# instantiate the nr object
nr = InitNornir(config_file="config.yaml")
# let's filter it down to simplify the output
cmh = nr.filter(site="cmh", type="host")

def count(task: Task, number: int) -> Result:
    return Result(
        host=task.host,
        result=f"{[n for n in range(0, number)]}"
    )

def say(task: Task, text: str) -> Result:
    if task.host.name == "host2.cmh":
        raise Exception("I can't say anything right now")
    return Result(
        host=task.host,
        result=f"{task.host.name} says {text}"
    )

現(xiàn)在用一個我們上節(jié)教程中用過的例子:

def greet_and_count(task: Task, number: int):
    task.run(
        name="Greeting is the polite thing to do",
        severity_level=logging.DEBUG,
        task=say,
        text="hi!",
    )

    task.run(
        name="Counting beans",
        task=count,
        number=number,
    )
    task.run(
        name="We should say bye too",
        severity_level=logging.DEBUG,
        task=say,
        text="bye!",
    )

    # let's inform if we counted even or odd times
    even_or_odds = "even" if number % 2 == 1 else "odd"
    return Result(
        host=task.host,
        result=f"{task.host} counted {even_or_odds} times!",
    )

大家記著我們在host2.cmh上設(shè)置了一個錯誤,現(xiàn)在我們執(zhí)行這個任務(wù)看下將會發(fā)生什么:

result = cmh.run(
    task=greet_and_count,
    number=5,
)

讓我們看下這個result對象:

print(result.faild)

輸出:
True

print(result.faild_hosts)

輸出:
{'host2.cmh': MultiResult: [Result: "greet_and_count", Result: "Greeting is the polite thing to do"]}

print(result['host2.cmh'].exception)

輸出:
Subtask: Greeting is the polite thing to do (failed)

print(result['host2.cmh'][1].exception)

輸出:
I can't say anything right now

如你所見,result對象是意識到了一些錯誤的,如果你想看的話也可以查看。
你也可以用print_result函數(shù):

print_result(result)

輸出:
greet_and_count*****************************************************************
* host1.cmh ** changed : False *************************************************
vvvv greet_and_count ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
host1.cmh counted even times!
---- Counting beans ** changed : False ----------------------------------------- INFO
[0, 1, 2, 3, 4]
^^^^ END greet_and_count ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* host2.cmh ** changed : False *************************************************
vvvv greet_and_count ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv ERROR
Subtask: Greeting is the polite thing to do (failed)

---- Greeting is the polite thing to do ** changed : False --------------------- ERROR
Traceback (most recent call last):
  File "/home/bless/.local/lib/python3.8/site-packages/nornir/core/task.py", line 99, in start
    r = self.task(self, **self.params)
  File "/mnt/d/Project/nornir_learn2/learn_failed_tasks.py", line 20, in say
    raise Exception("I can't say anything right now")
Exception: I can't say anything right now

^^^^ END greet_and_count ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

還有一個方法可以拋出異常如果task又錯誤的話(目前我還沒看出來這個怎么應(yīng)用):

from nornir.core.exceptions import NornirExecutionError
try:
    result.raise_on_error()
except NornirExecutionError:
    print("ERROR!!!")

輸出:
ERROR!!!

Skipped hosts

Norni會跟蹤任務(wù)失敗的hosts,并且不會在這些hosts中執(zhí)行接下來的任務(wù):

#這段代碼必須要加在前面的后面才可以感受到
#host2.cmh這個host在前面的任務(wù)中失敗,所以在執(zhí)行這個hi時Nornir會直接跳過
def hi(task: Task) -> Result:
    return Result(host=task.host, result=f"{task.host.name}: Hi, I am still here!")

result = cmh.run(task=hi)
print_result(result)

輸出:
hi******************************************************************************
* host1.cmh ** changed : False *************************************************
vvvv hi ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
host1.cmh: Hi, I am still here!
^^^^ END hi ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

你可以通過傳遞這個參數(shù)on_failed=True,來強制執(zhí)行:

result = cmh.run(task=hi, on_failed=True)

print_result(result)

輸出:
hi******************************************************************************
* host1.cmh ** changed : False *************************************************
vvvv hi ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
host1.cmh: Hi, I am still here!
^^^^ END hi ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
* host2.cmh ** changed : False *************************************************
vvvv hi ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
host2.cmh: Hi, I am still here!

你還可以排除一些執(zhí)行成功的host,通過on_good這個參數(shù):

result = cmh.run(task=hi, on_failed=True, on_good=False)
print_result(result)

輸出:

hi******************************************************************************
* host2.cmh ** changed : False *************************************************
vvvv hi ** changed : False vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv INFO
host2.cmh: Hi, I am still here!
^^^^ END hi ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

為了實現(xiàn)這個,Nornir保留了一個共享的data對象,存儲一系列失敗的hosts

print(nr.data.failed_hosts)

輸出:
{'host2.cmh'}

如果你想把一些hosts變成成功的并且使他們執(zhí)行后續(xù)的任務(wù),可以同對單獨的host執(zhí)行recover_host函數(shù)或者通過reset_failed_hosts重置整個列表。

nr.data.reset_failed_hosts()
print(nr.data.failed_hosts)

輸出:
set()

Raise on error automatically

另外,可以通過raise_on_error配置選項來實現(xiàn)錯誤發(fā)生時自動拋出異常:

nr = InitNornir(config_file="config.yaml", core={"raise_on_error": True})
cmh = nr.filter(site="cmh", type="host")
try:
    result = cmh.run(
        task=greet_and_count,
        number=5,
    )
except NornirExecutionError:
    print("ERROR!!!")

輸出:
ERROR!!!

Workflows

默認的工作流適用于大多數(shù)的用例,當(dāng)錯誤發(fā)生時跳過這些host,并且print_result會給出足夠的信息去里理解發(fā)生了什么。對于更復(fù)雜的工作流,這個框架會提供足夠的空間去輕松部署。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容