जब फैब्रिक में त्रुटि मिलती है तो किसी कार्य को कैसे जारी रखें


94

जब मैं कई दूरस्थ सर्वरों पर चलने के लिए किसी कार्य को परिभाषित करता हूं, यदि कार्य सर्वर एक पर चलता है और एक त्रुटि के साथ बाहर निकलता है, तो फैब्रिक बंद हो जाएगा और कार्य को रद्द कर देगा। लेकिन मैं कपड़े को त्रुटि की अनदेखी करना और अगले सर्वर पर कार्य चलाना चाहता हूं। मैं यह कैसे कर सकता हूं?

उदाहरण के लिए:

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

जवाबों:


146

से डॉक्स :

... कपड़ा "विफल-तेज़" व्यवहार पैटर्न में चूक करता है: अगर कुछ भी गलत हो जाता है, जैसे कि एक दूरस्थ कार्यक्रम जो नॉनजेरो रिटर्न वैल्यू लौटा रहा है या आपका फैबाइल पायथन कोड अपवाद का सामना कर रहा है, तो निष्पादन तुरंत रुक जाएगा।

यह आमतौर पर वांछित व्यवहार है, लेकिन नियम के कई अपवाद हैं, इसलिए फैब्रिक env.warn_only, बूलियन सेटिंग प्रदान करता है। यह गलत करने के लिए चूक करता है, जिसका अर्थ है कि एक त्रुटि स्थिति कार्यक्रम को तुरंत निरस्त कर देगी। हालाँकि, अगर env.warn_only विफलता के समय True पर सेट है - साथ, कहते हैं, सेटिंग्स संदर्भ प्रबंधक - फैब्रिक एक चेतावनी संदेश का उत्सर्जन करेगा लेकिन निष्पादित करना जारी रखेगा।

ऐसा लगता है कि आप ठीक-ठाक नियंत्रण का उपयोग कर सकते हैं, जहाँ settingsसंदर्भ प्रबंधक का उपयोग करके त्रुटियों को अनदेखा किया जाता है , ऐसा कुछ:

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

13
आयात करने के लिए मत भूलनाfrom fabric.api settings
cevaris

31

फैब्रिक 1.5 के रूप में, एक प्रसंग प्रबंधक है जो इसे आसान बनाता है:

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

आप कपड़े के किस संस्करण का उपयोग कर रहे हैं? मैं सिर्फ फैब्रिक == 1.6.2 के साथ सेवानिवृत्त हुआ, और यह ठीक काम करता है।
क्रिस मैरिनो जूल

संभवतः, मैं फैब्रिक == 1.9.0 का उपयोग कर रहा हूं और यह मेरे लिए काम नहीं करता है
सेवारिस

अभी 1.9.0 पर भी परीक्षण किया गया है। जब आप मेरी अद्यतन टिप्पणी से उदाहरण कोड की कोशिश करते हैं तो आपका आउटपुट क्या होता है?
क्रिस मैरिनो जूल

यदि आप चेतावनियों / त्रुटियों को प्रिंट नहीं करना चाहते हैं, तो आप छिपाने के संदर्भ प्रबंधक का भी उपयोग कर सकते हैं :with hide('everything'):
np8

13

आप पूरी स्क्रिप्ट की चेतावनी भी सेट कर सकते हैं

def local():
    env.warn_only = True

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.

आप इसे एक ब्लॉक के साथ भी सेट कर सकते हैं। यहाँ प्रलेखन देखें ।


इसके लिए धन्यवाद, लेकिन एक प्रश्न - क्या वर्तमान कपड़े में संभव पहुंच / पास है जैसा कि अपवाद के रूप में परिभाषित किया गया है? (इसलिए मैं अपवाद के साथ कुछ विशिष्ट सेटिंग्स को प्रिंट कर सकता हूं।)
ब्रायन

@ ब्रायन: क्या आप fabric.api.envअपने exceptब्लॉक के भीतर की जाँच नहीं कर सकते ?
आर्टऑफवर्फ

@ArtOfWarefare आह आह मुझे चुपचाप मैं कोशिश कर रहा था / छोड़कर अपने सभी कार्यों को लपेटने से बचने की कोशिश कर रहा था और इसके बजाय बस सेट करें env.abort_exception=MyExceptionताकि मैं अपनी खुद की असफलता को चला सकूं । यह "काम करता है" की तरह अगर मैं एक वर्ग के बजाय एक फ़ंक्शन का उपयोग करता हूं (के लिए कॉल करने योग्य अनुरोध को संतुष्ट करता है abort_exception) लेकिन मैं अभी भी उस दृष्टिकोण के साथ कुछ अन्य मुद्दों पर काम कर रहा हूं।
ब्रायन

@ ब्रायन: तो उस फंक्शन की बॉडी के अंदर यह देख लें कि क्या fabric.api.envहै।
ArtOfWarfare

7

फैब्रिक 1.3.2 में कम से कम, आप अपवाद को पकड़कर अपवाद को पुनर्प्राप्त कर सकते SystemExitहैं। यदि आपके पास एक से अधिक बैच में चलने के लिए (जैसे एक तैनाती) कमांड है और यदि उनमें से कोई एक विफल रहता है तो सफाई करना चाहते हैं तो यह मददगार है।


+1: परीक्षण किया गया - यह फैब्रिक 1.9.0 में भी काम करता है। इसे पकड़ने के बाद, आप SystemExitअधिक विवरण के लिए संदेश या कोड की जांच कर सकते हैं ।
ArtOfWarfare

पकड़ने से भी बेहतर SystemExit, abort_exceptionएक अलग अपवाद पर सेट करें, ताकि आप गलती से अपवाद न पकड़ें जिसका फैब्रिक से कोई लेना-देना नहीं है। एक उदाहरण के लिए मेरा जवाब देखें: stackoverflow.com/a/27990242/901641
ArtOfWarfare

7

में कपड़ा 2.x तुम सिर्फ उपयोग कर सकते हैं आह्वान के रन के साथ चेतावनी दी = सच तर्क। वैसे भी, इनवोक फैब्रिक 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)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.