Kiedy zdefiniuję zadanie do uruchomienia na kilku zdalnych serwerach, jeśli zadanie zostanie uruchomione na serwerze pierwszym i zakończy się z błędem, Fabric zatrzyma i przerwie zadanie. Ale chcę, aby tkanina ignorowała błąd i uruchamiała zadanie na następnym serwerze. Jak mogę to zrobić?
Na przykład:
$ 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.
from fabric.api settings
Począwszy od Fabric 1.5, istnieje ContextManager, który to ułatwia:
from fabric.api import sudo, warn_only with warn_only(): sudo('mkdir foo')
Aktualizacja: Ponownie potwierdziłem, że to działa w ipythonie, używając następującego kodu.
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')
źródło
with hide('everything'):
Możesz również ustawić warn_only całego skryptu na wartość true z
def local(): env.warn_only = True
źródło
Powinieneś ustawić
abort_exception
zmienną środowiskową i złapać wyjątek.Na przykład:
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.
Możesz również ustawić go w bloku with. Zobacz dokumentację tutaj .
źródło
fabric.api.env
w swoimexcept
bloku?env.abort_exception=MyException
tak, żebym mógł uruchomić własny błąd. To trochę "działa", jeśli używam funkcji zamiast klasy (spełnia wymaganie wywoływalne dlaabort_exception
), ale wciąż pracuję nad innymi problemami z tym podejściem.fabric.api.env
jest.Przynajmniej w Fabric 1.3.2 możesz odzyskać wyjątek, przechwytując go
SystemExit
. Jest to przydatne, jeśli masz więcej niż jedno polecenie do uruchomienia w trybie wsadowym (np. Wdrożenie) i chcesz wyczyścić, jeśli jedno z nich zawiedzie.źródło
SystemExit
wiadomość lub kod użytkownika, aby uzyskać więcej informacji.SystemExit
, ustawabort_exception
inny wyjątek, aby przypadkowo nie złapać wyjątków, które nie mają nic wspólnego z Fabric. Zobacz moją odpowiedź na przykład: stackoverflow.com/a/27990242/901641W Fabric 2.x można po prostu użyć invoke „s run z ostrzec = true argumentu. W każdym razie wywołanie jest zależne od Fabric 2.x :
from invoke import run run('bad command', warn=True)
Z poziomu zadania:
from invoke import task @task def my_task(c): c.run('bad command', warn=True)
źródło
W moim przypadku na Fabric> = 1,4 ta odpowiedź była poprawna.
Możesz pominąć złe hosty, dodając to:
env.skip_bad_hosts = True
Lub przekroczyć
--skip-bad-hosts
flagę /źródło